我有一个我正在计算的脚本:
def sumsquared(arr):
sum = 0
idx = 0
len = arr.__len__()
while idx < (len - 1):
sum = sum + (arr[idx] * arr[idx]) + (arr[idx+1] * arr[idx+1])
idx = idx + 2
return sum
上面的函数在循环中调用,该循环填充两个列表并调用此函数两次:第一次使用len~1024项目列表,第二次使用len~44100项目。根据输入,循环本身可以运行100到100000次。
对于小尺寸输入,基于cProfile
的分析通知我:
ncalls tottime percall cumtime percall filename:lineno(function)
---------------------------------------------------------------------
2560 12.065 0.005 12.065 0.005 beat.py:8(sumsquared)
大约是脚本总运行时间的95%。有什么方法可以加快这项功能吗?
答案 0 :(得分:5)
你的功能很奇怪。它所做的就是计算元素的平方和,除非如果有奇数个元素,它会抛弃最后一个元素。您出于某种原因一次添加两个,但这不会影响最终结果。
为了加快速度,您可以使用numpy而不是编写自己的函数。
>>> x = np.array([1, 2, 3, 4, 5])
>>> sumsquared(x)
30
>>> (x[:2*(len(x)//2)]**2).sum()
30
一般来说,如果你有数千个数字的列表,那么使用numpy数组可能会带来重大的性能提升。
答案 1 :(得分:3)
这看起来像是itertools module:
的工作def sumsquared(arr):
s = sum(itertools.imap(operator.mul, arr, arr))
return s - arr[-1] ** 2 if len(arr) & 1 else s
使用 sum ,运算符和 itertools 将消除几乎所有纯python开销。
此外,当输入为整数,浮点数或两者的某些混合时, sum 已经过优化,以接近C速度运行。它可以累积运行总计,而无需为每个中间小计创建纯python对象。
信用:罗伯特·金在必要时减去最终方格的想法。
另外注意,如果您对获得高准确度(即最小化精度损失)感兴趣,请考虑使用math.fsum代替 sum 。
答案 2 :(得分:2)
这是我能找到的最快的
from itertools import imap
from operator import mul
def sumsquared(arr):
return sum(imap(mul, arr, arr))
答案 3 :(得分:1)
sum([i**2 for i in arr]) - (arr[-1]**2 if len(arr) % 2 else 0)