我有以下代码:
import time
from threading import Thread
from multiprocessing import Process
def fun1():
for _ in xrange(10000000):
print 'in fun1'
pass
def fun2():
for _ in xrange(10000000):
print 'in fun2'
pass
def fun3():
for _ in xrange(10000000):
print 'in fun3'
pass
def fun4():
for _ in xrange(10000000):
print 'in fun4'
pass
if __name__ == '__main__':
#t1 = Thread(target=fun1, args=())
t1 = Process(target=fun1, args=())
#t2 = Thread(target=fun2, args=())
t2 = Process(target=fun2, args=())
#t3 = Thread(target=fun3, args=())
t3 = Process(target=fun3, args=())
#t4 = Thread(target=fun4, args=())
t4 = Process(target=fun4, args=())
t1.start()
t2.start()
t3.start()
t4.start()
start = time.clock()
t1.join()
t2.join()
t3.join()
t4.join()
end = time.clock()
print("Time Taken = ",end-start)
'''
start = time.clock()
fun1()
fun2()
fun3()
fun4()
end = time.clock()
print("Time Taken = ",end-start)
'''
我以三种方式运行上述程序:
end_time-start时间的观察结果如下:
总体运行时间
问题:
我看到顺序执行花费的时间最少,多线程占用时间最长。为什么?我无法理解,也对结果感到惊讶。请澄清。
由于这是一项CPU密集型任务并且获得了GIL,我的理解是 线程执行需要花费最多时间,多处理将花费最少的时间。请验证我的理解。
答案 0 :(得分:8)
你使用Product.ToList().ForEach(i => {
i.GetType().GetProperties().ToList().ForEach( p =>{
p.SetValue(i, p.GetValue(i).ToString().Replace(" ",String.Empty));});
i.GetType().GetFields().ToList().ForEach( p =>{
p.SetValue(i, p.GetValue(i).ToString().Replace(" ",String.Empty));});
});
,它给你CPU时间而不是实时:你不能在你的情况下使用它,因为它给你执行时间(你使用CPU运行你的代码多长时间,对于每一种情况几乎都是同一时间)
使用time.clock
而不是time.time()
运行代码,这样我就可以在计算机上使用这些代码:
time.clock
此处给出的任务(打印)速度非常快,以至于使用多处理的速度几乎可以通过开销来平衡。
对于Process : ('Time Taken = ', 5.226783990859985)
seq : ('Time Taken = ', 6.3122560000000005)
Thread : ('Time Taken = ', 17.10062599182129)
,由于GIL只能运行一个Thread,所以最终会顺序运行所有函数但是你有线程开销(每隔几次迭代更改一次就可能花费几毫秒)每一次)。所以你最终得到的东西要慢得多。
Threading
很有用,所以你可以在两者之间运行任务。
Threading
对于计算成本高昂的任务非常有用,如果可能的话,完全独立(没有共享变量)。如果你需要共享变量,那么你必须面对GIL并且它有点复杂(但大多数时候并非不可能)。
编辑:实际上,像您一样使用Multiprocessing
向您提供了有关使用time.clock
和Threading
花费多少开销的信息。
答案 1 :(得分:0)
基本上你是对的。 您使用什么平台来运行代码段?我想Windows。 请注意,“print”不受CPU约束因此您应该注释掉“print”并尝试在Linux上运行它以查看差异(它应该是您所期望的)。 使用这样的代码:
def fun1():
for _ in xrange(10000000):
# No print, and please run on linux
pass