我的i7 7700HQ上的Python多处理性能明显比非并行性能慢。
在计划在 mssql 中并行化我的单表数据库的选择和更新代码时,我尝试首先并行化一个简单的代码。该程序只是打印参数的倍数。我尝试了单线程,多进程与进程对象和池对象。单线程始终表现最佳。
import time
def foobar(a):
for i in range(1,10000):
print(a*i)
return
if __name__ == "__main__":
Tthreading = time.clock()
p1= Process(target= foobar, args=(3,))
p2 = Process(target= foobar, args= (2,))
p3 = Process(target= foobar, args= (4,))
p4 = Process(target=foobar, args=(123,))
allprocess.start
allprocess.join
print(time.clock() - Tthreading)
#Single-threaded
Tsingle = time.clock()
foobar(3)
foobar(2)
foobar(4)
foobar(123)
print(time.clock() - Tsingle)
我预计多进程会快得多,因为没有共享资源(没有函数,需要在线程之间访问的变量(和 IPC。
单线程时间:0.32s
多进程时间:0.53s
实际上,您的示例中有一个重要的共享资源,即显示器(或stdout
(。
print
是一个相对较慢的操作(与 CPU 周期相比...(,它会导致进程之间的争用。
正确对并行工作进行基准测试是一项艰巨的任务,它受到 CPU 的许多因素和功能(例如缓存(的影响。
尝试用非常适合多处理的工作负载替换您的工作负载(例如,在数组的不同部分并行工作,矩阵乘法......
还有一件重要的事情:催生新流程也需要时间,要使每个流程中完成的工作得到回报,需要付出巨大的代价。如果你稍微增加你的循环范围,差异应该有利于多进程版本:
import time
from multiprocessing import Process
def foobar(a):
for i in range(1,10000000):
a*i
return
if __name__ == "__main__":
Tthreading = time.time()
p1= Process(target= foobar, args=(3,))
p2 = Process(target= foobar, args= (2,))
p3 = Process(target= foobar, args= (4,))
p4 = Process(target=foobar, args=(123,))
allprocess = [p1,p2,p3,p4]
for p in allprocess:
p.start()
for p in allprocess:
p.join()
print(time.time() - Tthreading)
#Single-threaded
Tsingle = time.time()
foobar(3)
foobar(2)
foobar(4)
foobar(123)
print(time.time() - Tsingle)
在我的机器上,这输出:
0.44509196281433105
1.3775699138641357