Si consideri la seguente funzione:Multiprocessing di Python - Perché usare functools.partial più lentamente degli argomenti predefiniti?
def f(x, dummy=list(range(10000000))):
return x
Se uso multiprocessing.Pool.imap
, ottengo i seguenti orari:
import time
import os
from multiprocessing import Pool
def f(x, dummy=list(range(10000000))):
return x
start = time.time()
pool = Pool(2)
for x in pool.imap(f, range(10)):
print("parent process, x=%s, elapsed=%s" % (x, int(time.time() - start)))
parent process, x=0, elapsed=0
parent process, x=1, elapsed=0
parent process, x=2, elapsed=0
parent process, x=3, elapsed=0
parent process, x=4, elapsed=0
parent process, x=5, elapsed=0
parent process, x=6, elapsed=0
parent process, x=7, elapsed=0
parent process, x=8, elapsed=0
parent process, x=9, elapsed=0
Ora, se io uso functools.partial
invece di utilizzare un valore di default:
import time
import os
from multiprocessing import Pool
from functools import partial
def f(x, dummy):
return x
start = time.time()
g = partial(f, dummy=list(range(10000000)))
pool = Pool(2)
for x in pool.imap(g, range(10)):
print("parent process, x=%s, elapsed=%s" % (x, int(time.time() - start)))
parent process, x=0, elapsed=1
parent process, x=1, elapsed=2
parent process, x=2, elapsed=5
parent process, x=3, elapsed=7
parent process, x=4, elapsed=8
parent process, x=5, elapsed=9
parent process, x=6, elapsed=10
parent process, x=7, elapsed=10
parent process, x=8, elapsed=11
parent process, x=9, elapsed=11
Perché la versione che utilizza functools.partial
è molto più lenta?
Perché stai usando 'lista (intervallo (...))'? AFAIK il tuo codice farebbe esattamente la stessa cosa senza la chiamata a 'list', tranne che il problema spiegato da ShadowRanger non si verificherebbe e il sovraccarico del pickling sarebbe * molto * più piccolo. – Bakuriu
Side-note: Usare 'list's (o qualsiasi altro tipo mutable) come argomento predefinito (o' partial' bound) è pericoloso, dal momento che la _same_ 'lista' è condivisa tra tutte le invocazioni predefinite della funzione, non una nuova copia per ogni chiamata; di solito, vuoi la nuova copia. – ShadowRanger
come nota a parte, di solito è una pessima idea usare l'oggetto mutevole come valori predefiniti perché se lo si modifica nella funzione ogni successiva chiamata alla funzione vedrà le modifiche – Copperfield