Betrachten Sie die folgende Funktion:Python Multiprocessing - Warum ist functools.partial langsamer als Standardargumente?
def f(x, dummy=list(range(10000000))):
return x
Wenn ich multiprocessing.Pool.imap
verwenden, erhalte ich die folgenden Timings:
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
Nun, wenn ich functools.partial
anstatt mit einem Standardwert verwenden:
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
Warum ist die Version mit functools.partial
so viel langsamer?
Warum verwenden Sie 'Liste (Bereich (...))'? AFAIK Ihr Code würde genau dasselbe ohne den Aufruf von 'list' machen, außer dass das von ShadowRanger erklärte Problem nicht auftritt und der Aufwand für das Beizen viel * kleiner wäre. – Bakuriu
Side-Anmerkung: Mit 'list's (oder einem anderen wandelbaren Typ) als Standard (oder' partial' gebunden) Argumente ist gefährlich, da die _same_ 'list' zwischen all Standard Anrufungen der Funktion freigegeben ist, nicht eine neue Kopie für jeden Anruf; Normalerweise möchten Sie die frische Kopie. – ShadowRanger
als beiseite beachten Sie, dass in der Regel keine gute Idee veränderbares Objekt als Standardwerte verwenden, denn wenn man es in der Funktion auf die Funktion jeder nachfolgenden Aufruf ändern wird um die Änderungen sehen – Copperfield