Python 优化列表上的简单数学计算

Python 优化列表上的简单数学计算,python,optimization,Python,Optimization,我有一个我正在计算的脚本: 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 这大约占脚本总运行时间的95%。有什么方

我有一个我正在计算的脚本:

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

这大约占脚本总运行时间的95%。有什么方法可以加快函数的速度吗?

您的函数非常奇怪。它所做的只是计算元素的平方和,但如果元素数为奇数,它会丢弃最后一个元素。出于某种原因,一次添加两个,但这不会影响最终结果

为了加快速度,您可以使用而不是编写自己的函数

>>> x = np.array([1, 2, 3, 4, 5])
>>> sumsquared(x)
30
>>> (x[:2*(len(x)//2)]**2).sum()
30

通常,如果您有数千个数字的列表,那么使用numpy阵列可能会带来显著的性能提升。

这看起来像是一项针对以下用户的工作:

使用sum、operator和itertools将消除几乎所有纯python开销

此外,当输入为整数、浮点或两者的混合时,sum已优化为以接近C的速度运行。它能够累积运行总计,而无需为每个中间小计创建纯python对象

赞誉:罗伯特·金提出了在必要时减去最后一个平方的想法


另一个注意事项,如果你对获得高精度(即最小化精度损失)感兴趣,考虑使用而不是求和。

< P>这是我能找到的最快的< /P>
from itertools import imap
from operator import mul
def sumsquared(arr):
    return sum(imap(mul, arr, arr))

也许是这样,但您可以更具体一点。
成对返回
(s0,s1)、(s1,s2)
问题询问的
(s0,s1)、(s2,s3)
。您应该能够使用len=len(arr),无需调用。u len@monkut不起作用,因为函数中的
len
是一个局部变量,它将阻止访问内置
len()
。然而,WeaklyTyped应该能够执行
length=len(arr)
yes,或者只使用len(arr)本身而不是创建变量。在这种情况下,不是每次循环检查条件时都会调用len(arr)吗?你真的应该执行
sum(i**2表示arr中的i)
。您的方法将计算整个列表,然后在该列表上迭代以对元素求和。我建议使用生成器理解而不是列表理解。在我的测试中,generator comprehension将运行时间缩短到OP算法的近50%。Guido今天说,“除非你知道你有大量的值列表需要迭代,否则我不会使用generator[expression]s。在内存分配变得至关重要之前,具体的列表[comprehension]通常比genexpr更快。”-与numpy阵列之间的转换非常昂贵。通常只有在一起执行一系列操作时才有意义。@gnibbler:是的,但这就是我在末尾添加位的原因。如果您有44000个数字的列表,那么您应该从一开始就使用numpy数组。
def sumsquared(arr):
    s = sum(itertools.imap(operator.mul, arr, arr))
    return s - arr[-1] ** 2 if len(arr) & 1 else s
sum([i**2 for i in arr]) - (arr[-1]**2 if len(arr) % 2 else 0)
from itertools import imap
from operator import mul
def sumsquared(arr):
    return sum(imap(mul, arr, arr))