Function call execution speed is faster than non-function call
函数调用总是会产生一些开销。但是为什么下面的代码显示非函数调用较慢。
代码:1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import time def s(): for i in range(1000000000): 1 + 1 t = time.time() s() print("Function call:" + str(time.time() - t)) t = time.time() for i in range(1000000000): 1 + 1 print("Non function call:" + str(time.time() - t)) |
输出:
1 2 | Function call: 38.39736223220825 Non function call: 60.33238506317139 |
您可能会认为,由于循环只执行
在函数中,这是通过
记住,函数调用只发生一次。所以它的开销在这个特定的场景中并没有真正的作用。
除此之外,所有其他步骤都发生过一次,而且几乎是相同的。创建一个范围,获取其迭代器,并为每个迭代加载常量
正如@moses在评论中指出的那样,您总是可以使用
1 2 3 4 5 6 7 8 | dis.dis(s) # snipped for brevity >> 10 FOR_ITER 8 (to 20) 12 STORE_FAST 0 (i) 3 14 LOAD_CONST 3 (2) 16 POP_TOP 18 JUMP_ABSOLUTE 10 |
而对于循环的顶级版本:
1 2 3 4 5 6 7 | dis('for i in range(1000000000): 1+1') # snipped for brevity >> 10 FOR_ITER 8 (to 20) 12 STORE_NAME 1 (i) 14 LOAD_CONST 3 (2) 16 POP_TOP 18 JUMP_ABSOLUTE 10 |
它们之间的主要区别在于存储迭代值
要解决@reblochon masque(现已删除)的问题,在ipython细胞中,当与
1 2 3 4 | from timeit import Timer t = Timer('for i in range(10000): 1 + 1') print(t.src) |
它包含基本上是定时的小函数。以前的
1 2 3 4 5 6 7 | def inner(_it, _timer): pass _t0 = _timer() for _i in _it: for i in range(10000): 1 + 1 _t1 = _timer() return _t1 - _t0 |
因此,实际上,通过使用
(如果你不相信我,见《以东记》〔19〕)