2013-06-30 13 views
13

Ich habe mit Python arbeiten und ich die folgenden Code Situation auf:Python functools Teileffizienz

import timeit 

setting = """ 
import functools 

def f(a,b,c): 
    pass 

g = functools.partial(f,c=3)  
h = functools.partial(f,b=5,c=3) 
i = functools.partial(f,a=4,b=5,c=3) 
""" 

print timeit.timeit('f(4,5,3)', setup = setting, number=100000) 
print timeit.timeit('g(4,5)', setup = setting, number=100000) 
print timeit.timeit('h(4)', setup = setting, number=100000) 
print timeit.timeit('i()', setup = setting, number=100000) 

ich folgenden als Ergebnis erhalten:

f: 0.181384086609 
g: 0.39066195488 
h: 0.425783157349 
i: 0.391901016235 

Warum die Anrufe an den Teilfunktionen dauern länger? Versetzt die Teilfunktion die Parameter nur an die ursprüngliche Funktion oder bildet sie die statischen Argumente vollständig ab? Und gibt es auch eine Funktion in Python, um den Körper einer ausgefüllten Funktion zurückzugeben, vorausgesetzt, dass alle Parameter wie bei Funktion i vordefiniert sind?

Antwort

15

Warum dauern die Aufrufe der Teilfunktionen länger?

Der Code mit partial dauert etwa zwei Mal länger wegen der zusätzlichen Funktionsaufruf. Funktionsaufrufe are expensive:

Funktionsaufruf in Python ist relativ hoch, insbesondere verglichen mit der Ausführungsgeschwindigkeit einer eingebauten Funktion.

-

Ist die Teilfunktion die Parameter an die ursprüngliche Funktion nur die Weiterleitung oder es wird die Abbildung der statischen Argumente im ganzen?

Soweit ich weiß - ja, es ist nur forwards the arguments to the original function.

-

Und auch gibt es eine Funktion in Python den Körper einer Funktion gefüllt zurück in gegeben, dass alle Parameter vorgegeben sind, wie mit der Funktion i?

Nein, mir ist eine solche integrierte Funktion in Python nicht bekannt. Aber ich denke, es ist möglich zu tun, was Sie wollen, denn Funktionen sind Objekte, die kopiert und verändert werden können. Hier

ist ein Prototyp:

import timeit 
import types 


# http://stackoverflow.com/questions/6527633/how-can-i-make-a-deepcopy-of-a-function-in-python 
def copy_func(f, name=None): 
    return types.FunctionType(f.func_code, f.func_globals, name or f.func_name, 
     f.func_defaults, f.func_closure) 


def f(a, b, c): 
    return a + b + c 


i = copy_func(f, 'i') 
i.func_defaults = (4, 5, 3) 


print timeit.timeit('f(4,5,3)', setup = 'from __main__ import f', number=100000) 
print timeit.timeit('i()', setup = 'from __main__ import i', number=100000) 

die gibt:

0.0257439613342 
0.0221881866455 
+0

Danke für die Hilfe. Gibt es eine Chance, dass Sie oder jemand mir einen Tipp geben könnte, wie das geht? Würde es das Manipulieren des Byte-Code-Objekts (Funktion .__ Code__) oder kann es nur durch das Funktionsobjekt erfolgen? – user2515310

+0

Ich habe meine Antwort aktualisiert. Aber sind Sie wirklich besorgt über die Geschwindigkeit? Was ist dein Problem? – warvariuc

+0

Sie sind absolut erstaunlich. Vielen Dank. Und aus Gründen der Interessen arbeite ich an einer Python-API und wollte eine Möglichkeit für einen Entwickler, eine Funktion für ein Element zu definieren und dann diese Funktion in eine schnelle Schleife einzufügen, aber die Funktion ruft in der Python-Implementierung auf, mit der ich arbeite prohibitive to speed (wie aus meinen timeit-Ergebnissen ersichtlich ist). – user2515310