Was ist der einfachste Weg, um diesen Code zu parallelisieren?
Ich mag concurrent.futures
das sehr, verfügbar in Python3 seit Version 3.2 - und über Backport auf 2.6 und 2.7 auf PyPi .
Sie können Threads oder Prozesse verwenden und genau dieselbe Schnittstelle verwenden.
Mehrfachverarbeitung
Legen Sie dies in eine Datei - 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()
Und hier ist die Ausgabe:
$ 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
Wechseln Sie nun ProcessPoolExecutor
zu ThreadPoolExecutor
und führen Sie das Modul erneut aus:
$ 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]
Jetzt haben Sie sowohl Multithreading als auch Multiprocessing durchgeführt!
Hinweis zur Leistung und zur gemeinsamen Verwendung beider.
Die Stichprobe ist viel zu klein, um die Ergebnisse zu vergleichen.
Ich vermute jedoch, dass Multithreading schneller ist als Multiprocessing im Allgemeinen, insbesondere unter Windows, da Windows das Forking nicht unterstützt und jeder neue Prozess einige Zeit zum Starten benötigt. Unter Linux oder Mac werden sie wahrscheinlich näher sein.
Sie können mehrere Threads in mehreren Prozessen verschachteln. Es wird jedoch empfohlen, nicht mehrere Threads zu verwenden, um mehrere Prozesse auszulagern.
calc_stuff
?