tipos propias parametros otra llamar lista funciones funcion ejemplos dentro python function partial functools

propias - self en python



Funciones de Python de eficiencia parcial. (2)

¿Por qué las llamadas a las funciones parciales llevan más tiempo?

El código con partial tarda aproximadamente dos veces más debido a la llamada de función adicional. Las llamadas a funciones son caras:

La sobrecarga de llamadas a funciones en Python es relativamente alta, especialmente en comparación con la velocidad de ejecución de una función incorporada.

-

¿La función parcial está simplemente enviando los parámetros a la función original o está asignando los argumentos estáticos a lo largo?

Por lo que sé, sí, simplemente reenvía los argumentos a la función original .

-

Y también, ¿existe una función en Python para devolver el cuerpo de una función completada dado que todos los parámetros están predefinidos, como con la función i?

No, no soy consciente de tal función incorporada en Python. Pero creo que es posible hacer lo que quieras, ya que las funciones son objetos que se pueden copiar y modificar.

Aquí hay un prototipo:

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)

lo que da:

0.0257439613342 0.0221881866455

He estado trabajando con Python y configuré la siguiente situación de código:

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)

Me sale lo siguiente como resultado:

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

¿Por qué las llamadas a las funciones parciales llevan más tiempo? ¿La función parcial está simplemente enviando los parámetros a la función original o está asignando los argumentos estáticos a lo largo? Y también, ¿existe una función en Python para devolver el cuerpo de una función completada dado que todos los parámetros están predefinidos, como con la función i?


Las llamadas a una función con argumentos parcialmente aplicados son más caras porque duplicas el número de llamadas de función. El efecto de functools.partial() es similar a este ejemplo:

def apply_one_of_two(f, a): def g(b): return f(a, b) return g

Eso significa que apply_one_of_two() devuelve una función y, cuando se llama, resulta en la llamada adicional de la función original f .

Como Python generalmente no optimiza esto, se traduce directamente en esfuerzos de tiempo de ejecución adicionales.

Pero este no es el único factor a considerar en su microbenchmark. También cambia de posición a argumentos de palabras clave en sus invocaciones parciales, lo que introduce una sobrecarga adicional.

Cuando invierte el orden de los argumentos en su función original, no necesita argumentos de palabras clave en las llamadas parciales y, a continuación, la diferencia de tiempo de ejecución disminuye un poco, por ejemplo:

import timeit setting = """ import functools def f(a,b,c): pass g = functools.partial(f, 4) h = functools.partial(f, 4, 5) i = functools.partial(f, 4, 5, 3) """ print(timeit.timeit(''f(4, 5, 3)'', setup = setting, number=100000)) print(timeit.timeit(''g(5, 3)'', setup = setting, number=100000)) print(timeit.timeit(''h(3)'', setup = setting, number=100000)) print(timeit.timeit(''i()'', setup = setting, number=100000))

Salida (en un Intel Skylake i7 bajo Fedora 27 / Python 3.6):

0.010069019044749439 0.01681053702486679 0.018060395028442144 0.011366961000021547