[英]How to make this Python program faster using multithreading?
我做了一個簡單的程序來執行一些數學運算,我想使用多線程讓它更快。 我知道 Python 的 GIL 會阻止真正的多線程處理,但仍然存在可以改善執行時間的情況。
在這種情況下,程序的線程和非線程執行時間似乎相似,因此似乎沒有任何性能改進。 我知道多處理模塊,但由於它在執行共享 memory 操作時的限制,我想避免這種情況。 有什么方法可以使用多線程在這個程序中顯着提高速度?
謝謝
import string, random, threading
def getLetters():
letterList = []
for letter in string.ascii_lowercase:
letterList.append(letter)
return letterList
def getNum(letter):
letterVal = ord(letter)
rand = random.randint(1,5000000)
result = 0
for num in range(0,rand):
if num%2 == 0:
result+=num
else:
result-=num
result*=letterVal
print(f"Result: {result}")
return result
def mainWithThreading():
letters = getLetters()
threadList = []
for letter in letters:
th = threading.Thread(target=getNum, args=[letter], daemon=True)
threadList.append(th)
for th in threadList:
th.start()
for th in threadList:
th.join()
def mainWithoutThreading():
letters = getLetters()
for letter in letters:
getNum(letter)
start = time.time()
mainWithoutThreading()
end = time.time()
print(f"Time taken: {end-start:.2f}s\n")
start = time.time()
mainWithThreading()
end = time.time()
print(f"Time taken: {end-start:.2f}s\n")
一些代碼發生了變化——主要是為了利用多處理,但也刪除了一些冗余。
from concurrent.futures import ProcessPoolExecutor
from string import ascii_letters
from random import randint
from time import perf_counter
def getNum(c):
letterVal = ord(c)
result = 0
for num in range(randint(1, 5_000_000)):
# the calculations within this loop serve no purpose other
# than to make Python do "work"
if num % 2 == 0:
result += num
else:
result -= num
result *= letterVal
return result
def main():
start = perf_counter()
with ProcessPoolExecutor() as executor:
executor.map(getNum, ascii_letters)
end = perf_counter()
print(f'Duration after subprocess mapping = {end-start:.2f}s')
start = perf_counter()
for c in ascii_letters:
getNum(c)
end = perf_counter()
print(f'Duration after linear processing = {end-start:.2f}s')
if __name__ == '__main__':
main()
Output:
Duration after subprocess mapping = 1.35s
Duration after linear processing = 8.68s
筆記:
由於getNum() function 中的隨機化,您需要運行幾次才能更清楚地了解多處理如何為這類事情帶來好處。 更好的測試是去掉隨機因素。
通過將getNum()中的循環更改為 200 萬的恆定范圍,結果是:
Duration after subprocess mapping = 1.08s
Duration after linear processing = 7.69s
...這是一個更現實的測試
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.