使用if / else或字典的更好的优化技术

时间:2012-07-12 04:57:56

标签: python algorithm

哪种更优化?

  • 接收'string'的一系列if / else语句返回适当的函数。 (大约40-50 if / else语句)。
  • 维护键值对的字典。 key作为字符串,值作为函数对象,以及一个搜索和返回函数对象的主函数。

使用上述方法实际返回函数对象的主函数将被调用数百或数十亿次,因此需要智能地执行此操作。什么是更好的方法?

例如

dict['str1'] = func1
dict['str2'] = func2
and so on..

def main_func(str):
    return dict[str]

或者

def main_func(str):
    if 'str1':
      return func1
    elif 'str2':
      return func2

哪个更好..?如果我们有50-60个这样的字符串,这个过程需要数十亿次。

在函数本身中将函数对象存储在字典中: -

def func1():
   if dict.has_key('str1'):
        dict['str1'] = func1
   -- do something --

哪个更好,这个或上面的。这看起来更干净。?但请记住,这些函数会多次调用,因此has_key函数也会多次调用。

谢谢

7 个答案:

答案 0 :(得分:13)

选择字典。

字典......

  • 是内置的
  • 是pythonic
  • 需要较少的样板代码
  • 与if-else线性O(n)复杂度相比,
  • 具有O(1)复杂度
  • 没有过早的悲观情绪(我们没有充分的理由相信,如果没有分析它是一种效率较低的方法)

我建议先使用字典编写解决方案,然后查看解决方案是否足够快以满足您的需求。如果是这样,很好,你已经完成了。如果没有,请反对其他方式。

考虑这样的解决方案(如果找不到字符串,将返回None):

func_dict = {}
func_dict['str1'] = fun1
func_dict['str2'] = fun2
...
def function_lookup(func_string):
    return func_dict.get(func_string)

然后,在您的主要内容中,只需编写function_lookup(whatever_string_variable)即可尝试查找您的函数。这样可以避免每次调用function_lookup时重建字典。

答案 1 :(得分:6)

字典会更快:它大约是O(1),而if语句链是O(n)。为了演示,这个脚本(make_test.py)将输出一个运行一些性能测试的python脚本:

ifs = []
dict = []
for i in range(60):
    string = 'str%d' % i
    ifs.append('  %sif str == "%s": return %d' % ('el' if i else '', string, i))
    dict.append('"%s": %d' % (string, i))

print 'dict = {', ','.join(dict), '}'
print 'def with_dict(str):'
print '  return dict[str]'

print 'def with_if(str):'
print '\n'.join(ifs)

print '''
import timeit

def test_dict():
    for i in range(60):
        with_dict("str%d" % i)

def test_if():
    for i in range(60):
        with_if("str%d" %i)

print 'dict:', timeit.timeit(test_dict, number=10000)
print 'if:  ', timeit.timeit(test_if, number=10000)'''

python make_test.py | python一样运行,给我:

dict: 0.706176042557
if:   1.67383503914

也就是说,if版本比dict版本慢2倍。

答案 2 :(得分:2)

从技术上讲,它取决于哈希冲突性能,但我想将所有数据存储在哈希中并检索它将稍微更快。

无论如何,差异可能不会很大。当然哈希表解决方案更清晰,所以我建议这样做。

最明确的方法是编写两个版本并使用大量数据对其进行测试并测量其性能。

答案 3 :(得分:1)

字典更好。 Dictionary应该由树/ hashmap支持,并且比if-else语句(大致是线性的)具有更好的时间复杂度。即使实际运行时间不是更好,代码也会用字典更清晰。

答案 4 :(得分:1)

字典是python中经过深度调整的部分之一。它们产生更易读的代码。 它们应该比if循环表现更好。 但是,考虑到插入和其他开销,我建议您使用timeit模块并检查性能。

答案 5 :(得分:0)

dict lookup的平均时间复杂度为O(1)。最坏的情况是O(n)。只有str键(你的用例)的字典有优化。

假设if / else梯形图中的测试顺序本身不能根据输入频率进行优化(例如60种可能性,其中2种情况发生在95%的时间),一系列if的复杂性/ else语句是O(n)。

因此,字典将提供更好的性能以及更好的代码可读性。

答案 6 :(得分:0)

每个解决方案看起来都更优雅,更易于维护。

在大多数应用程序编程中,更重要的是优化人工时间和可维护性,然后优化计算机时间。电脑时间很便宜。人的时间很贵。

这两种解决方案都有其优势。

如果您需要稍后添加控制流,if / elif解决方案可以提供更大的灵活性,例如嵌套if / else。

如果数据直接来自yaml或数据库等数据源,那么显然dict解决方案更优雅。