为什么在Python中内联if/else比.get()快?
我之前查看了一些代码,开发人员编写了一个内联的为什么在Python中内联if/else比.get()快?,python,performance,Python,Performance,我之前查看了一些代码,开发人员编写了一个内联的if/else而不是get(),以从列表中检索元素(如果它存在的话)(否则给它一个默认值)。我决定在repl上弹出一些timeit代码,结果让我非常困惑。if/else花费get()时间的1/3 ,以下是repl中的代码以及子孙后代的结果: import timeit D = {"a": 1, "b": 2, "c": 3} def ef(): return D['a'] if 'a' in D else 1 def gt(): return
if
/else
而不是get()
,以从列表中检索元素(如果它存在的话)(否则给它一个默认值)。我决定在repl上弹出一些timeit
代码,结果让我非常困惑。if
/else
花费get()
时间的1/3
,以下是repl中的代码以及子孙后代的结果:
import timeit
D = {"a": 1, "b": 2, "c": 3}
def ef(): return D['a'] if 'a' in D else 1
def gt(): return D.get('a', 1)
print "gt1", timeit.timeit(gt, number=10000)
print "ef1", timeit.timeit(ef, number=10000)
print "ef2", timeit.timeit(ef, number=10000)
print "gt2", timeit.timeit(gt, number=10000)
结果是:
gt1 0.0659999847412
ef1 0.0239999294281
ef2 0.0249998569489
gt2 0.0539999008179
以及上述timeit
调用的10次迭代的可视化结果,其中结果已乘以10000以表示
路径D.get()
包括属性查找和方法调用:
>>> import dis
>>> D = {"a": 1, "b": 2, "c": 3}
>>> def gt(): return D.get('a', 1)
...
>>> dis.dis(gt)
1 0 LOAD_GLOBAL 0 (D)
3 LOAD_ATTR 1 (get)
6 LOAD_CONST 1 ('a')
9 LOAD_CONST 2 (1)
12 CALL_FUNCTION 2
15 RETURN_VALUE
属性查找(LOAD\u ATTR
)尤其会减慢速度
如果删除属性查找(并在测试中提供要使用的),则该字段将变得均匀:
>>> def gt_fast(D_get=D.get): return D_get('a', 1)
...
>>> def ef_fast(D=D): return D['a'] if 'a' in D else 1
...
>>> timeit.timeit(gt_fast)
0.2174091339111328
>>> timeit.timeit(ef_fast)
0.2139298915863037
为什么不快一点呢?我几乎总是希望内置语言语法比方法调用更快。你的假设是正确的。我只是希望内置函数在字典上的开销比我们必须引用字典值的条件函数要低。对,但是函数显然也必须引用字典值,对吗?否则,当密钥存在时,它将如何返回所述值?在应用程序的关键路径期间,这是否在紧循环中?如果不是的话,我无法想象你为什么会在意计时。@JohnSchmitt你会笑……但我曾经生成它,因为我不想激发pycharm或excel。