如何在Python中高效地执行大循环加法

5

我正尝试在Python中以更高效的方式进行大循环加法运算。我想循环迭代100000000个数字的范围。

from datetime import datetime

start_time = datetime.now()
sum = 0
for i in range(100000000):
    sum+=i
end_time = datetime.now()
print('--- %s seconds ---{}'.format(end_time - start_time))
print(sum)

以上代码的输出结果是 --- %s 秒 ---0:00:16.662666 4999999950000000

当我尝试在C语言中执行此操作时,需要 0.43 秒。

根据我所读到的内容,每次对变量执行加法操作时,Python都会创建新的内存。我阅读了一些文章,并了解了如何在这种情况下避免使用 '+' 符号来执行字符串拼接。但我没有找到任何关于整数的方法。


3
为什么要用循环?(n**2 + n)/2 可以比任何循环更快地提供相同的答案。 - Ethan
很有可能C语言并没有执行循环,而只是将结果存储在二进制中。您有什么使用情况需要执行此操作,但无法将其简化为结果? - MisterMiyagi
2个回答

6

如果您可以将列表作为整体进行处理,请考虑使用sum()函数,该函数完全在C代码中循环,速度更快,也避免了创建新的Python对象。

sum(range(100000000))

在我的电脑中,您的代码需要07.189210秒来运行,而上述语句只需要02.751251秒,加快了处理速度超过3倍。
编辑:如mtrw所建议的那样,使用numpy.sum()可以进一步提高处理速度。

谢谢 @Alex Metsei - Pramod Kumar
“避免创建新的Python对象”是什么意思? - Kelly Bundy
我的错误,我是指他有一个变量,在每一步中都会增加,但现在想想那并不重要,毕竟我也使用了一个变量。你想建议修改吗? - Alex Metsai
1
如果我没记错的话,这是半真的,因为部分不是Python对象由于一种优化。然而,range产生的数字仍然是Python对象。嗯,我不想建议修改。 - Kelly Bundy
我明白了,好的。顺便说一下,谢谢你的见解^^ - Alex Metsai
显示剩余2条评论

5
这里是三种方法的比较:你原来的方式,使用 sum(range(100000000))(由Alex Metsai提出),以及使用NumPy数值库的sumrange函数。
from datetime import datetime
import numpy as np

def orig():
    start_time = datetime.now()
    sum = 0
    for i in range(100000000):
        sum+=i
    end_time = datetime.now()
    print('--- %s seconds ---{}'.format(end_time - start_time))
    print(sum)

def pyway():
    start_time = datetime.now()
    mysum = sum(range(100000000))
    end_time = datetime.now()
    print('--- %s seconds ---{}'.format(end_time - start_time))
    print(mysum)

def npway():
    start_time = datetime.now()
    sum = np.sum(np.arange(100000000))
    end_time = datetime.now()
    print('--- %s seconds ---{}'.format(end_time - start_time))
    print(sum)

在我的电脑上,我看到:

>>> orig()
--- %s seconds ---0:00:09.504018
4999999950000000
>>> pyway()
--- %s seconds ---0:00:02.382020
4999999950000000
>>> npway()
--- %s seconds ---0:00:00.683411
4999999950000000

如果您的应用程序可以使用NumPy,则它是最快的。

但是,正如Ethan在评论中建议的那样,值得指出的是直接计算答案是 远远 最快的方法:

def mathway():
    start_time = datetime.now()
    mysum = 99999999*(99999999+1)/2
    end_time = datetime.now()
    print('--- %s seconds ---{}'.format(end_time - start_time))
    print(mysum)


>>> mathway()
--- %s seconds ---0:00:00.000013
4999999950000000.0

我猜想您的实际问题不是那么容易用纸笔解决 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接