nim*_*ima 5 python performance-testing nested-function
我希望尽可能使用嵌套函数而不是Python中的方法或全局函数.所以我决定测试它们的性能,因为当你在另一个函数中定义一个函数时,在外部函数的每次调用中都会有内部函数定义的开销.
充其量我希望全局函数稍微快一点,但令人惊讶的是嵌套函数更快.有谁知道为什么?
这是我的代码:
from time import clock
def a(n):
return n + 1
def b1(loopcount):
return sum([a(n) for n in range(loopcount)])
def b2(loopcount):
def a(n):
return n + 1
return sum([a(n) for n in range(loopcount)])
powers = [5, 6, 7]
b1times = []
b2times = []
print " ", "".join(["{:^10d}".format(n) for n in powers])
for i in range(5):
for power in powers:
t = clock()
b1(10**power)
b1times.append(clock() - t)
for power in powers:
t = clock()
b2(10**power)
b2times.append(clock() - t)
print "b1:", "".join(["{:^10.5f}".format(n) for n in b1times])
print "b2:", "".join(["{:^10.5f}".format(n) for n in b2times])
print ""
b1times = []
b2times = []
Run Code Online (Sandbox Code Playgroud)
这是我的电脑上的结果:
5 6 7
b1: 0.08200 0.82773 8.47946
b2: 0.06914 0.79637 8.18571
b1: 0.07332 0.82139 8.68262
b2: 0.06547 0.82088 8.19606
b1: 0.07963 0.82625 9.65037
b2: 0.06617 0.82027 8.21412
b1: 0.07630 0.82112 8.49082
b2: 0.06541 0.80686 8.20532
b1: 0.12328 0.87034 8.42964
b2: 0.07059 0.79717 8.24620
Run Code Online (Sandbox Code Playgroud)
更新:使用@Janne Karila的评论
现在我更多地调用b1和b2,b1变得更快.所以@Kos和@Pavel Anossov在他们的答案中说了一些因素影响了这里的速度,你不能做出一般性陈述.
感谢大家!
from time import *
def a1(n):
return n + 1
def b1(n):
return a1(n)
def b2(n):
def a2():
return n + 1
return a2()
powers = [4, 5, 6]
b1times = []
b2times = []
print " ", "".join(["{:^10d}".format(n) for n in powers])
for i in range(5):
for power in powers:
t = clock()
sum([b1(n) for n in range(10**power)])
b1times.append(clock() - t)
for power in powers:
t = clock()
sum([b2(n) for n in range(10**power)])
b2times.append(clock() - t)
print "b1:", "".join(["{:^10.5f}".format(n) for n in b1times])
print "b2:", "".join(["{:^10.5f}".format(n) for n in b2times])
print ""
b1times = []
b2times = []
Run Code Online (Sandbox Code Playgroud)
Kos*_*Kos 10
这里有几个部分有效:
1)定义函数的时间(创建函数对象),
2)按名称查找函数对象
的时间,3)实际调用函数的时间.
您的全局函数示例更快1)(无需a在每次调用时重新定义b1).但是,它在2)中较慢,因为全局变量查找比本地查找慢.
为什么我们不能同时拥有?
我已经使用全局函数扩展了您的基准测试,但避免使用局部变量进行全局查找.它似乎是我机器上三个中最快的:
5 6 7
b1: 0.04147 0.44421 4.46508
b2: 0.03399 0.43321 4.41121
b3: 0.03258 0.41821 4.25542
b1: 0.03240 0.42998 4.39774
b2: 0.03320 0.43465 4.42229
b3: 0.03155 0.42109 4.23669
b1: 0.03273 0.43321 4.37266
b2: 0.03326 0.43551 4.42208
b3: 0.03137 0.42356 4.25341
b1: 0.03253 0.43104 4.40466
b2: 0.03401 0.43719 4.42996
b3: 0.03155 0.41681 4.24132
b1: 0.03244 0.42965 4.37192
b2: 0.03310 0.43629 4.42727
b3: 0.03117 0.41701 4.23932
Run Code Online (Sandbox Code Playgroud)
LOAD_GLOBAL比LOAD_FAST慢得多.
5 0 LOAD_GLOBAL 0 (sum)
3 BUILD_LIST 0
6 LOAD_GLOBAL 1 (range)
9 LOAD_FAST 0 (loopcount)
12 CALL_FUNCTION 1
15 GET_ITER
>> 16 FOR_ITER 18 (to 37)
19 STORE_FAST 1 (n)
22 LOAD_GLOBAL 2 (a)
25 LOAD_FAST 1 (n)
28 CALL_FUNCTION 1
31 LIST_APPEND 2
34 JUMP_ABSOLUTE 16
>> 37 CALL_FUNCTION 1
40 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
8 0 LOAD_CONST 1 (<code object a at 01E57A40, ...>)
3 MAKE_FUNCTION 0
6 STORE_FAST 1 (a)
10 9 LOAD_GLOBAL 0 (sum)
12 BUILD_LIST 0
15 LOAD_GLOBAL 1 (range)
18 LOAD_FAST 0 (loopcount)
21 CALL_FUNCTION 1
24 GET_ITER
>> 25 FOR_ITER 18 (to 46)
28 STORE_FAST 2 (n)
31 LOAD_FAST 1 (a)
34 LOAD_FAST 2 (n)
37 CALL_FUNCTION 1
40 LIST_APPEND 2
43 JUMP_ABSOLUTE 25
>> 46 CALL_FUNCTION 1
49 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
每次创建函数的差异是否取决于函数(以及使用LOAD_GLOBAL的次数).
创建对内部循环中使用的全局函数的本地引用是一种相对常见的优化:
def a(n):
return n + 1
def b1(loopcount):
local_a = a
return sum([local_a(n) for n in range(loopcount)])
Run Code Online (Sandbox Code Playgroud)
这应该比查找全局且比嵌套函数更易维护更快.
| 归档时间: |
|
| 查看次数: |
1741 次 |
| 最近记录: |