python 中的多处理池花费了更多时间
Multiprocessing pool in python took more time
所以,我在 python 开始学习多处理。我为函数 'res' 创建了一个池。我对 运行 程序使用池并使用正常方式后的时间感兴趣,我认为如果我使用池处理时间会减少,但正如我所见,池花费了 10.0413179397583 秒,正常方式花费了 0.005002737045288086 秒(s).我错过了什么?
import multiprocessing as mp
import time
def res(a):
squ = 0
for i in range(a):
squ += i**2
return squ
if __name__ == "__main__":
t1 = time.time()
p = mp.Pool()
result = p.map(res, range(10000))
p.close()
p.join()
print(time.time()-t1)
t2 = time.time()
result = []
sum = 0
for i in range(10000):
sum += i**2
result.append(sum)
print(time.time()-t2)
您使用 multiprocessing
的算法是 O(n^2)
(1 循环,2 循环,... 9999 循环),而 "normal approach" 是 O(n)
.在没有 multiprocessing
的情况下,第一种方法在我的测试中花费了大约 3 倍的时间。
相关:What is a plain English explanation of “Big O” notation?
您的 pool
示例正在计算 10000
不同的循环,每个循环来自 0-9999
次迭代。您的第二个示例是 单 循环,具有 9999
次迭代...
这是一个 apples-to-apples 方法:
import multiprocessing as mp
import time
import sys
NUM_ITER = int(sys.argv[1])
def res(a):
squ = 0
for i in range(a):
squ += i**2
return squ
if __name__ == "__main__":
t1 = time.time()
p = mp.Pool(None)
result = p.map(res, range(NUM_ITER))
p.close()
p.join()
print(f"With multiprocessing: {time.time()-t1}")
t2 = time.time()
result = [res(i) for i in range(NUM_ITER)]
print(f"Without multiprocessing: {time.time()-t2}")
请注意,除非您进行大量迭代,否则 multiprocessing
会因为开销而花费更长的时间,因此请考虑:
Juans-MacBook-Pro:temp juan$ python -B timing_mp.py 100
With multiprocessing: 0.18288207054138184
Without multiprocessing: 0.002610921859741211
Juans-MacBook-Pro:temp juan$ python -B timing_mp.py 1000
With multiprocessing: 0.1448049545288086
Without multiprocessing: 0.16153407096862793
Juans-MacBook-Pro:temp juan$ python -B timing_mp.py 5000
With multiprocessing: 2.273800849914551
Without multiprocessing: 3.9749832153320312
Juans-MacBook-Pro:temp juan$ python -B timing_mp.py 10000
With multiprocessing: 8.837619066238403
Without multiprocessing: 15.725339889526367
就软件包 emcee 对此进行了精彩的讨论
如果函数调用的计算时间与多处理的开销相比不是相对较大,您将不会发现任何优势。您可以通过如下所示的函数调用相对轻松地演示这一点
import time
def func():
""" arbitrarily time-intensive function """
time.sleep(1) # return after 1 s "computation time"
return
所以,我在 python 开始学习多处理。我为函数 'res' 创建了一个池。我对 运行 程序使用池并使用正常方式后的时间感兴趣,我认为如果我使用池处理时间会减少,但正如我所见,池花费了 10.0413179397583 秒,正常方式花费了 0.005002737045288086 秒(s).我错过了什么?
import multiprocessing as mp
import time
def res(a):
squ = 0
for i in range(a):
squ += i**2
return squ
if __name__ == "__main__":
t1 = time.time()
p = mp.Pool()
result = p.map(res, range(10000))
p.close()
p.join()
print(time.time()-t1)
t2 = time.time()
result = []
sum = 0
for i in range(10000):
sum += i**2
result.append(sum)
print(time.time()-t2)
您使用 multiprocessing
的算法是 O(n^2)
(1 循环,2 循环,... 9999 循环),而 "normal approach" 是 O(n)
.在没有 multiprocessing
的情况下,第一种方法在我的测试中花费了大约 3 倍的时间。
相关:What is a plain English explanation of “Big O” notation?
您的 pool
示例正在计算 10000
不同的循环,每个循环来自 0-9999
次迭代。您的第二个示例是 单 循环,具有 9999
次迭代...
这是一个 apples-to-apples 方法:
import multiprocessing as mp
import time
import sys
NUM_ITER = int(sys.argv[1])
def res(a):
squ = 0
for i in range(a):
squ += i**2
return squ
if __name__ == "__main__":
t1 = time.time()
p = mp.Pool(None)
result = p.map(res, range(NUM_ITER))
p.close()
p.join()
print(f"With multiprocessing: {time.time()-t1}")
t2 = time.time()
result = [res(i) for i in range(NUM_ITER)]
print(f"Without multiprocessing: {time.time()-t2}")
请注意,除非您进行大量迭代,否则 multiprocessing
会因为开销而花费更长的时间,因此请考虑:
Juans-MacBook-Pro:temp juan$ python -B timing_mp.py 100
With multiprocessing: 0.18288207054138184
Without multiprocessing: 0.002610921859741211
Juans-MacBook-Pro:temp juan$ python -B timing_mp.py 1000
With multiprocessing: 0.1448049545288086
Without multiprocessing: 0.16153407096862793
Juans-MacBook-Pro:temp juan$ python -B timing_mp.py 5000
With multiprocessing: 2.273800849914551
Without multiprocessing: 3.9749832153320312
Juans-MacBook-Pro:temp juan$ python -B timing_mp.py 10000
With multiprocessing: 8.837619066238403
Without multiprocessing: 15.725339889526367
如果函数调用的计算时间与多处理的开销相比不是相对较大,您将不会发现任何优势。您可以通过如下所示的函数调用相对轻松地演示这一点
import time
def func():
""" arbitrarily time-intensive function """
time.sleep(1) # return after 1 s "computation time"
return