您实施的代码基本上是(a1+a2+ ... + an)/n
和(a1/n + a2/n + ... + an/n)
之间的差异。结果是一样的,但在第二个版本中有更多的操作(即(n-1)更多的分区),这减慢了计算速度。你声称在第二个版本中,每个循环运行独立于其他循环。在第一个循环中,我们需要以下信息来完成一次循环运行:运行前的total
和当前的value
。在第二个版本中,我们需要以下信息来完成一次循环运行:运行前的mean
,当前的value
和num_of_values
。正如你在第二个版本中看到的,我们甚至依赖更多的价值!
但是,我们如何分配核心之间的工作(这是多处理的目标)?我们可以给出一个核心的上半部分值和第二个下半部分,即((a1+a2+ ... + a(n//2)) + (a(n//2 +1) + ... + a(n))/n)
。是的,除以n的工作并不是在核心之间进行分割,而是一条指令,所以我们并不在乎。此外,我们还需要添加左边的总数和右边的总数,这是我们无法分割的,但它只是一次操作。
因此,代码,我们要运行:
def my_sum(values):
total = 0
for value in values:
total += value
return total
目前仍然使用python的一个问题 - 通常人们可以使用线程来执行计算,因为每个线程都使用一个核心。但在这种情况下,你必须注意你的程序不会遇到竞争条件,python解释器本身也需要照顾它。 CPython认为它不值得,基本上只能一次运行在一个线程中。一个基本的解决方案是通过多处理使用多个进程。
from multiprocessing import Pool
if __name__ == '__main__':
with Pool(5) as p:
results = p.map(my_sum, [long_list[0:len(long_list)//2], long_list[len(long_list)//2:]))
print(sum(results)/len(long_list)) # add subresults and divide by n
但当然多个过程不是免费的。你需要分叉,复制东西等,所以你不会像预期的那样获得加速。另外最大的放缓实际上是使用python本身,它不是真正为快速数值计算而优化的。有各种各样的方法,但使用numpy可能是最简单的。只需使用:
import numpy
print(numpy.mean(long_list))
这可能比python版本快得多。我不认为numpy使用多处理内部,所以可以通过使用多个进程和快速实现(numpy或其他用C编写的)来获得提升,但通常numpy足够快。
你是什么意思与异步?在python asyncio做异步IO,但这并不能真正帮助你。你想加快你的计算?看看numpy。如果你想在多核上运行,请查看多处理(python线程不能同时运行python代码)。你的第二个版本会做更多的工作(每次都是一个部门和一个加法),所以我不认为它需要更多时间是非常令人惊讶的。 – syntonym
@syntonym对不起,我的意思是并行不像异步,就像在多个线程中运行一样。我将如何使用多进程呢? – ChrisIkeokwu
第二个比较慢。更多的分裂! – sascha