这个Python代码的哪个版本更快?

时间:2011-11-15 00:27:02

标签: python optimization

只是一个学术问题。我很好奇这个代码的哪个版本在Python中更好(更快)?

var = random.randint(1, 10)
# First version
if var in [2, 5, 9]:
  print "First: 2, 5 or 9"

# Second version
if var == 2 or number == 5 or number == 9:
  print "Second: 2, 5 or 9"

这是一个非常简单的例子,但是如果变量var不是数字,而是字符串呢?

var = 'aaa'
# First version
if var in ['aaa', 'zzz', 'eee']:
  print "String"

一些更复杂的对象(不仅是数字或字符串,还有一些非常耗时的比较类)?

Python编译器内部会发生什么?我认为if var in list的执行方式如下:

for l in list:
  if l == var:
    print "String"

所以在我看来,第一个例子中的两个版本都是相同的(速度)。我是对的吗?

1 个答案:

答案 0 :(得分:7)

时间代码将显示哪个是最快的。使用 timeit 模块:

~ $ python -m timeit --setup 'var=2' 'var in [2, 5, 9]'
10000000 loops, best of 3: 0.0629 usec per loop
~ $ python -m timeit --setup 'var=5' 'var in [2, 5, 9]'
10000000 loops, best of 3: 0.0946 usec per loop
~ $ python -m timeit --setup 'var=9' 'var in [2, 5, 9]'
10000000 loops, best of 3: 0.117 usec per loop

~ $ python -m timeit --setup 'var=2' 'var == 2 or var==5 or var == 9'
10000000 loops, best of 3: 0.0583 usec per loop
~ $ python -m timeit --setup 'var=5' 'var == 2 or var==5 or var == 9'
10000000 loops, best of 3: 0.104 usec per loop
~ $ python -m timeit --setup 'var=9' 'var == 2 or var==5 or var == 9'
10000000 loops, best of 3: 0.127 usec per loop

如果你想提高你对Python在幕后做什么的直觉并知道哪个代码最快,请从disassembling code开始:

def f(x):
    var = random.randint(1, 10)
    # First version
    if var in [2, 5, 9]:
      print "First: 2, 5 or 9"

    # Second version
    if var == 2 or number == 5 or number == 9:
      print "Second: 2, 5 or 9"

import dis
dis.dis(f)

这将显示这个或那个或那个代码比列表执行更多步骤.__包含__ 版本。

FWIW,您可能也想要考虑使用集而不是列表。他们的O(1)查找倾向于根据关键频率击败列表(是最可能匹配的列表的第一个元素),以及散列函数的价格,以及元素的数量(集合比列表更好地扩展)他们的O(n)搜索:

if var in {2, 5, 9}:
    ...

在我的机器上,集合对搜索少量整数元素没有帮助:

~ $ python -m timeit --setup 'var=2' 'var in {2, 5, 9}'
1000000 loops, best of 3: 0.276 usec per loop
~ $ python -m timeit --setup 'var=5' 'var in {2, 5, 9}'
1000000 loops, best of 3: 0.281 usec per loop
~ $ python -m timeit --setup 'var=9' 'var in {2, 5, 9}'
1000000 loops, best of 3: 0.304 usec per loop