我正在研究Project Euler problem 12并提出以下解决方案:
import math
def main():
num = 0
j = 0
numFactors = 0
while numFactors <= 500:
j += 1
num = num + j #num = sum of numbers from 1 to j
#num = (j *(j+1))//2
numFactors = 0
for n in range(1,int(math.sqrt(num))):
if num % n == 0:
numFactors += 2
print(num)
if __name__ == '__main__':
from timeit import Timer
t = Timer(lambda: main())
print(t.timeit(number=1))
我的问题是针对num = num + j
的{{1}}行。
当仅使用单个加法时,程序始终比我取消注释下一行并执行乘法,加法和除法时要慢。
任何人都可以解释为什么单一操作比做3更慢?
答案 0 :(得分:1)
我实际上并没有发现我的机器性能有任何差异。如果乘法实际上比加法更快,我也会感到中庸。
我们可以使用dis
module来反汇编两个变体中的字节代码。两种变体中的大部分都是相同的,因此两种功能中的性能应该相同。这两个部分是不同的(第11行是num = num + j
,第12行是num = (j *(j+1))//2
):
11 43 LOAD_FAST 0 (num)
46 LOAD_FAST 1 (j)
49 BINARY_ADD
50 STORE_FAST 0 (num)
12 43 LOAD_FAST 1 (j)
46 LOAD_FAST 1 (j)
49 LOAD_CONST 3 (1)
52 BINARY_ADD
53 BINARY_MULTIPLY
54 LOAD_CONST 4 (2)
57 BINARY_FLOOR_DIVIDE
58 STORE_FAST 0 (num)
两个拆卸中都有三个操作。这里再次显示每个变体的唯一线:
11 43 LOAD_FAST 0 (num)
12 43 LOAD_FAST 1 (j)
49 LOAD_CONST 3 (1)
53 BINARY_MULTIPLY
54 LOAD_CONST 4 (2)
57 BINARY_FLOOR_DIVIDE
如果乘法真的比加法快,那么我希望精通字节码的人可以解释为什么LOAD_FAST
num
比第12行的五个操作快。但是我的外行人看来,我希望使用更多字节码操作的变体需要更长的时间。