Python importar X o desde X importar Y? (actuación)

Si hay una biblioteca desde la cual usaré al menos dos métodos, ¿hay alguna diferencia en el rendimiento o el uso de memoria entre los siguientes?

from X import method1, method2 

y

 import X 

Hay una diferencia, porque en la versión import x hay dos búsquedas de nombres: una para el nombre del módulo y la segunda para el nombre de la función; por otro lado, utilizando from x import y , solo tiene una búsqueda.

Puedes ver esto bastante bien, usando el módulo dis:

 import random def f_1(): random.seed() dis.dis(f_1) 0 LOAD_GLOBAL 0 (random) 3 LOAD_ATTR 0 (seed) 6 CALL_FUNCTION 0 9 POP_TOP 10 LOAD_CONST 0 (None) 13 RETURN_VALUE from random import seed def f_2(): seed() dis.dis(f_2) 0 LOAD_GLOBAL 0 (seed) 3 CALL_FUNCTION 0 6 POP_TOP 7 LOAD_CONST 0 (None) 10 RETURN_VALUE 

Como puede ver, usar el formulario from x import y es un poco más rápido.

Por otro lado, import x es menos costoso que from x import y , porque hay un nombre que busca menos; veamos el código desensamblado:

 def f_3(): import random dis.dis(f_3) 0 LOAD_CONST 1 (-1) 3 LOAD_CONST 0 (None) 6 IMPORT_NAME 0 (random) 9 STORE_FAST 0 (random) 12 LOAD_CONST 0 (None) 15 RETURN_VALUE def f_4(): from random import seed dis.dis(f_4) 0 LOAD_CONST 1 (-1) 3 LOAD_CONST 2 (('seed',)) 6 IMPORT_NAME 0 (random) 9 IMPORT_FROM 1 (seed) 12 STORE_FAST 0 (seed) 15 POP_TOP 16 LOAD_CONST 0 (None) 19 RETURN_VALUE 

No sé la razón, pero parece que la forma from x import y parece una llamada de función, y por lo tanto es aún más costosa de lo anticipado; por esta razón, si la función importada se usa solo una vez, significa que sería más rápido usar import x , mientras que si se usa más de una vez, se vuelve más rápido de usar from x import y .

Dicho esto, como de costumbre, sugeriría que no siga este conocimiento para tomar una decisión sobre cómo importar módulos y funciones, porque esto es solo una optimización prematura.
Personalmente, creo que en muchos casos, los espacios de nombres explícitos son mucho más legibles, y le sugiero que haga lo mismo: use su propio sentido de estética 🙂

No hay memoria ni diferencia de velocidad (todo el módulo debe evaluarse de cualquier manera, porque la última línea podría ser Y = something_else ). A menos que su computadora sea de los años 80, no importa de todos modos.

No creo que haya ninguna diferencia real, y en general preocuparse por esa pequeña cantidad de memoria no suele valer la pena. Si va a presionar consideraciones de memoria, es mucho más probable que esté en su código.

Puede importar si llama a una función muchas veces en un bucle (millones o más). Hacer la búsqueda de doble diccionario eventualmente se acumulará. El siguiente ejemplo muestra un aumento del 20%.

Los tiempos indicados son para Python 3.4 en una máquina Win7 de 64 bits. (Cambie el comando de rango a xrange para Python 2.7).

Este ejemplo se basa en gran medida en el libro High Performance Python , aunque su tercer ejemplo de búsquedas de funciones locales que son mejores ya no me parece válido.

 import math from math import sin def tight_loop_slow(iterations): """ >>> %timeit tight_loop_slow(10000000) 1 loops, best of 3: 3.2 s per loop """ result = 0 for i in range(iterations): # this call to sin requires two dictionary lookups result += math.sin(i) def tight_loop_fast(iterations): """ >>> %timeit tight_loop_fast(10000000) 1 loops, best of 3: 2.56 s per loop """ result = 0 for i in range(iterations): # this call to sin only requires only one lookup result += sin(i)