Cách dễ nhất để song song mã này là gì?
Tôi thực sự thích concurrent.futures
điều này, có sẵn trong Python3 kể từ phiên bản 3.2 - và thông qua backport đến 2.6 và 2.7 trên PyPi .
Bạn có thể sử dụng các chủ đề hoặc quy trình và sử dụng cùng một giao diện.
Đa xử lý
Đặt cái này trong một tập tin - futuretest.py:
import concurrent.futures
import time, random # add some random sleep time
offset = 2 # you don't supply these so
def calc_stuff(parameter=None): # these are examples.
sleep_time = random.choice([0, 1, 2, 3, 4, 5])
time.sleep(sleep_time)
return parameter / 2, sleep_time, parameter * parameter
def procedure(j): # just factoring out the
parameter = j * offset # procedure
# call the calculation
return calc_stuff(parameter=parameter)
def main():
output1 = list()
output2 = list()
output3 = list()
start = time.time() # let's see how long this takes
# we can swap out ProcessPoolExecutor for ThreadPoolExecutor
with concurrent.futures.ProcessPoolExecutor() as executor:
for out1, out2, out3 in executor.map(procedure, range(0, 10)):
# put results into correct output list
output1.append(out1)
output2.append(out2)
output3.append(out3)
finish = time.time()
# these kinds of format strings are only available on Python 3.6:
# time to upgrade!
print(f'original inputs: {repr(output1)}')
print(f'total time to execute {sum(output2)} = sum({repr(output2)})')
print(f'time saved by parallelizing: {sum(output2) - (finish-start)}')
print(f'returned in order given: {repr(output3)}')
if __name__ == '__main__':
main()
Và đây là đầu ra:
$ python3 -m futuretest
original inputs: [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
total time to execute 33 = sum([0, 3, 3, 4, 3, 5, 1, 5, 5, 4])
time saved by parallellizing: 27.68999981880188
returned in order given: [0, 4, 16, 36, 64, 100, 144, 196, 256, 324]
Đa luồng
Bây giờ thay đổi ProcessPoolExecutor
thành ThreadPoolExecutor
và chạy lại mô-đun:
$ python3 -m futuretest
original inputs: [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
total time to execute 19 = sum([0, 2, 3, 5, 2, 0, 0, 3, 3, 1])
time saved by parallellizing: 13.992000102996826
returned in order given: [0, 4, 16, 36, 64, 100, 144, 196, 256, 324]
Bây giờ bạn đã thực hiện cả đa luồng và đa xử lý!
Lưu ý về hiệu suất và sử dụng cả hai cùng nhau.
Lấy mẫu là quá nhỏ để so sánh kết quả.
Tuy nhiên, tôi nghi ngờ rằng đa luồng sẽ nhanh hơn đa xử lý nói chung, đặc biệt là trên Windows, vì Windows không hỗ trợ giả mạo nên mỗi quy trình mới phải mất thời gian để khởi chạy. Trên Linux hoặc Mac, có lẽ họ sẽ gần gũi hơn.
Bạn có thể lồng nhiều luồng trong nhiều tiến trình, nhưng không nên sử dụng nhiều luồng để tách ra nhiều tiến trình.
calc_stuff
gì?