我目前正在创建一个模拟数学问题的简单脚本。问题是“ Frog 问题”,提出了 here由 standupmaths 的 Matt Parker 在他的 YouTube channel 上发表。但基本上,问题是关于一只 Frog 试图逐步从河流的一侧跳到另一侧的泥土上。我的代码通过从剩余的 lillypads 数量中减去一个随机数并继续直到该数字为 0 来模拟这一点。
这就是全部:
import random
import datetime
from multiprocessing import Pool
def frog_time(num_lillypads):
jumps = 0
while num_lillypads > 0:
num_lillypads -= random.randint(1, num_lillypads)
jumps += 1
return jumps
def frog_run(num_lillypads, iterations=10000):
ave = 0
print("Running {} lillypads.".format(num_lillypads))
for i in range(1, iterations+1):
ave = (ave*(i-1)+frog_time(num_lillypads))/i
return ave
def single_run(max_lillypads, iterations):
start = datetime.datetime.now()
results = []
for i in range(1, max_lillypads+1):
results.append(frog_run(i, iterations))
time_taken = datetime.datetime.now() - start
return time_taken
def timing_run(max_lillypads, iterations):
start = datetime.datetime.now()
with Pool() as pool:
pad_nos = list(range(1, max_lillypads+1))
results = pool.map(frog_run, range(1, max_lillypads+1))
time_taken = datetime.datetime.now() - start
return time_taken
def test(max=1000, iters=10000):
print("Concurrent run")
concurrent_time = timing_run(max, iters)
print("Single run")
single_time = single_run(max, iters)
print("Single run took {} to finish.".format(single_time))
print("Concurrent run took {} to finish.".format(concurrent_time))
我决定将此作为 Python 并发编程的练习,但我预计会有截然不同的结果。 当我运行它时,我得到:
Single run took 0:01:55.825933 to finish.
Concurrent run took 0:02:00.110245 to finish.
我认为实现多处理的运行至少会快一点,如果不是明显快的话,但在这种情况下它实际上需要更长的时间!
任何了解 python 多处理的人都可以通过解释这个结果来帮助我吗?为其中每一个创建一个新进程的开销是否太大而无济于事,或者 python.random 太慢了,或者这还有其他问题吗?
最佳答案
现在,您没有指定要设置的进程数量,因此它将默认为最大值:[source]
processes is the number of worker processes to use. If processes is None then the number returned by os.cpu_count() is used.
每个工作进程需要 x
时间来设置。
那么,让我们使用一些任意值来看看我们是怎么做的:
- 该函数在一个进程中运行需要 120 秒
- 每个进程需要 5 秒才能启动
- 每个新进程都可以平分工作量
如果是这样的话:
- 无多处理:120 秒
- 2 个进程的多处理:60 秒 + 10 秒 = 70 秒
- 3 个进程的多处理:40 秒 + 15 秒 = 55 秒
- 4 个进程的多处理:30 秒 + 20 秒 = 50 秒
- 5 个进程的多处理:24 秒 + 25 秒 = 49 秒
- 6 个进程的多处理:20 秒 + 30 秒 = 50 秒
- 7 个进程的多处理:17 秒 + 35 秒 = 52 秒
因此,在某种程度上,您无法通过使用多处理获得 yield ,或者您可以将进程数量限制在与创建进程所浪费的时间相比仍能节省更多时间的范围内。
如果您使用 pool(2)
或 pool(3)
等,您可能会看到时间增加,然后再次减少。在更大规模的情况下,您拥有的流程越多越好,但在小规模的测试中情况可能并非如此。
关于python - Python 中的并发,多进程比单进程慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57995124/