为什么这种方法更快?
d = { 'a': funca }
为什么列表理解速度较慢?
x=list(range(0,1000000,3))
z=list(range(0,1000000,5))
y=list(range(0,1000000,15))
%timeit sum(x)+sum(z)-sum(y)
24 ms ± 1.25 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
我认为列表理解应该更快。还有其他比这两种方法更快的方法吗?
答案 0 :(得分:1)
第一个是列表理解,可以更快地将其删除,例如:
%timeit sum(i for i in range(1000000) if i % 3 == 0 or i % 5 == 0)
输出:
10 loops, best of 3: 47.5 ms per loop
但是第二个也可以更快,而无需在外部使用list
:
x=range(0,1000000,3)
z=range(0,1000000,5)
y=range(0,1000000,15)
%timeit sum(x)+sum(z)-sum(y)
输出:
1 loop, best of 3: 287 ms per loop
但是同样的事情,您仍然会想为什么它还会更快?
因为在第二个示例中您仍在遍历范围
另一个只是对发生器求和
要使其更快,请执行以下操作:
print(1000000//3 + 1000000//5 - 1000000//15)
%timeit 1000000//3 + 1000000//5 - 1000000//15
花费时间:
10000000 loops, best of 3: 31.3 ns per loop
答案 1 :(得分:0)
可能有两个部分会减慢第二个部分的速度:剩余函数(%)和必须遍历所有项目。第一个只需累加3、5或15的倍数,直至达到数字。
但是,如果您确实要最优化它,则应该使用整数除法:1000000//3 + 1000000//5 - 1000000//15
编辑:这不能回答问题,如Onyambu在下面评论的。一种更快的方法是找到平均值并乘以数字。例如,以下将计算小于或等于1000000的3的倍数之和:((1000000//3)*(1000000//3 * 3 + 3))//2
。这样可以找到3的倍数不超过1000000,并将其乘以最大倍数(1000000//3 * 3
)和最小倍数(3
)的平均值。