在lis上优化一个简单的数学计算

2024-05-29 04:37:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个计算脚本:

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%。有没有什么方法可以让我加快这个功能?你知道吗


Tags: 项目函数脚本列表lenreturn尺寸def
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已经过优化,当输入是int、float或两者的混合时,可以以接近C的速度运行。它能够累积运行总计,而无需为每个中间小计创建纯python对象。你知道吗

信贷:罗伯特金的想法减去最后的平方时,必要的。你知道吗

另一个注意事项是,如果您对获得高精度感兴趣(即最小化精度损失),请考虑使用math.fsum而不是sum。你知道吗

这是我能找到的最快的

from itertools import imap
from operator import mul
def sumsquared(arr):
    return sum(imap(mul, arr, arr))

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

为了更快,可以使用numpy而不是编写自己的函数。你知道吗

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

一般来说,如果您有数千个数字的列表,那么改用numpy数组可能会带来显著的性能提升。你知道吗

相关问题 更多 >

    热门问题