Apa cara termudah untuk memparalelkan kode ini?
Saya sangat suka concurrent.futures
untuk ini, tersedia dalam Python3 sejak versi 3.2 - dan via backport ke 2.6 dan 2.7 di PyPi .
Anda dapat menggunakan utas atau proses dan menggunakan antarmuka yang sama persis.
Multiprocessing
Masukkan ini ke dalam file - 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()
Dan inilah hasilnya:
$ 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]
Multithreading
Sekarang ubah ProcessPoolExecutor
menjadi ThreadPoolExecutor
, dan jalankan modul lagi:
$ 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]
Sekarang Anda telah melakukan multithreading dan multiprocessing!
Catat kinerja dan gunakan keduanya bersama-sama.
Pengambilan sampel terlalu kecil untuk membandingkan hasilnya.
Namun, saya menduga multithreading akan lebih cepat daripada multiprocessing secara umum, terutama pada Windows, karena Windows tidak mendukung forking sehingga setiap proses baru harus mengambil waktu untuk diluncurkan. Di Linux atau Mac mereka mungkin akan lebih dekat.
Anda dapat membuat sarang banyak utas di dalam beberapa proses, tetapi disarankan untuk tidak menggunakan beberapa utas untuk memulai beberapa proses.
calc_stuff
?