全域性直譯器鎖
由於 Global Interpreter Lock, Python 多執行緒效能通常會受到影響。簡而言之,即使你可以在 Python 程式中擁有多個執行緒,但無論 CPU 數量多少,任何時候只能有一個位元組碼指令並行執行。
因此,在外部事件(如網路訪問)阻止操作的情況下,多執行緒可能非常有效:
import threading
import time
def process():
time.sleep(2)
start = time.time()
process()
print("One run took %.2fs" % (time.time() - start))
start = time.time()
threads = [threading.Thread(target=process) for _ in range(4)]
for t in threads:
t.start()
for t in threads:
t.join()
print("Four runs took %.2fs" % (time.time() - start))
# Out: One run took 2.00s
# Out: Four runs took 2.00s
請注意,即使每個 process
執行 2 秒鐘,這四個程序一起能夠有效地並行執行,總共需要 2 秒。
但是,在 Python 程式碼中進行密集計算(例如大量計算)的情況下,多執行緒不會帶來太多改進,甚至可能比並行執行更慢:
import threading
import time
def somefunc(i):
return i * i
def otherfunc(m, i):
return m + i
def process():
for j in range(100):
result = 0
for i in range(100000):
result = otherfunc(result, somefunc(i))
start = time.time()
process()
print("One run took %.2fs" % (time.time() - start))
start = time.time()
threads = [threading.Thread(target=process) for _ in range(4)]
for t in threads:
t.start()
for t in threads:
t.join()
print("Four runs took %.2fs" % (time.time() - start))
# Out: One run took 2.05s
# Out: Four runs took 14.42s
在後一種情況下,多處理可以是有效的,因為多個程序當然可以同時執行多個指令:
import multiprocessing
import time
def somefunc(i):
return i * i
def otherfunc(m, i):
return m + i
def process():
for j in range(100):
result = 0
for i in range(100000):
result = otherfunc(result, somefunc(i))
start = time.time()
process()
print("One run took %.2fs" % (time.time() - start))
start = time.time()
processes = [multiprocessing.Process(target=process) for _ in range(4)]
for p in processes:
p.start()
for p in processes:
p.join()
print("Four runs took %.2fs" % (time.time() - start))
# Out: One run took 2.07s
# Out: Four runs took 2.30s