Mejora de la velocidad de importación del módulo Python

La pregunta sobre cómo acelerar la importación de módulos de Python se ha preguntado anteriormente ( Aceleración del cargador de “importación” de Python y Python: ¿Acelerar las importaciones? ) Pero sin ejemplos específicos y no ha dado soluciones aceptadas. Por lo tanto, volveré a abordar el tema aquí, pero esta vez con un ejemplo específico.

Tengo una secuencia de comandos de Python que carga una stack de imágenes en 3D del disco, la suaviza y la muestra como una película. Llamo a este script desde la línea de comandos del sistema cuando quiero ver rápidamente mis datos. Estoy de acuerdo con los 700 ms que se requieren para suavizar los datos, ya que esto es comparable a MATLAB. Sin embargo, se necesitan 650 ms adicionales para importar los módulos. Entonces, desde la perspectiva del usuario, el código Python se ejecuta a la mitad de la velocidad.

Esta es la serie de módulos que estoy importando:

import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation import scipy.ndimage import scipy.signal import sys import os 

Por supuesto, no todos los módulos son igualmente lentos para importar. Los principales culpables son:

 matplotlib.pyplot [300ms] numpy [110ms] scipy.signal [200ms] 

He experimentado con el uso from , pero esto no es más rápido. Como Matplotlib es el principal culpable y tiene una reputación de actualizaciones de pantalla lenta, busqué alternativas. Uno es PyQtGraph, pero se tarda 550 ms en importar.

Soy consciente de una solución obvia, que es llamar a mi función desde una sesión interactiva de Python en lugar del indicador de comandos del sistema. Esto está bien, pero es demasiado parecido a MATLAB, prefiero la elegancia de tener mi función disponible desde el indicador del sistema.

Soy nuevo en Python y no estoy seguro de cómo proceder en este momento. Como soy nuevo, apreciaría los enlaces sobre cómo implementar las soluciones propuestas. Idealmente, estoy buscando una solución simple (¡no todos!) Porque el código debe ser portátil entre varias máquinas Mac y Linux.

usted podría construir un servidor / cliente simple, el servidor ejecutándose y actualizando continuamente la ttwig, y ​​el cliente simplemente comunicando el siguiente archivo para procesar.

Escribí un ejemplo simple de servidor / cliente basado en el ejemplo básico de los documentos del módulo de socket : http://docs.python.org/2/library/socket.html#example

Aquí está server.py:

 # expensive imports import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation import scipy.ndimage import scipy.signal import sys import os # Echo server program import socket HOST = '' # Symbolic name meaning all available interfaces PORT = 50007 # Arbitrary non-privileged port s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((HOST, PORT)) s.listen(1) while 1: conn, addr = s.accept() print 'Connected by', addr data = conn.recv(1024) if not data: break conn.sendall("PLOTTING:" + data) # update plot conn.close() 

y client.py:

 # Echo client program import socket import sys HOST = '' # The remote host PORT = 50007 # The same port as used by the server s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST, PORT)) s.sendall(sys.argv[1]) data = s.recv(1024) s.close() print 'Received', repr(data) 

acaba de ejecutar el servidor:

 python server.py 

que realiza las importaciones, el cliente simplemente envía a través del socket el nombre del archivo nuevo para trazar:

 python client.py mytextfile.txt 

entonces el servidor actualiza la ttwig.

En mi máquina, ejecutar sus importaciones client.py 0.6 segundos, mientras que ejecuta client.py 0.03 segundos.

No es una respuesta real a la pregunta, pero una sugerencia sobre cómo puede crear un perfil de la velocidad de importación con Python 3.7 y atún (un pequeño proyecto mío):

 python3.7 -X importtime -c "import scipy" 2> scipy.log tuna scipy.log 

introduzca la descripción de la imagen aquí

Puede importar sus módulos manualmente en su lugar, utilizando imp . Vea la documentación aquí .

Por ejemplo, import numpy as np probablemente podría escribirse como

 import imp np = imp.load_module("numpy",None,"/usr/lib/python2.7/dist-packages/numpy",('','',5)) 

Esto evitará que Python explore su sys.path completo para encontrar los paquetes deseados.

Ver también:

La importación manual de gtk falla: módulo no encontrado

1.35 segundos no es largo, pero supongo que si estás acostumbrado a la mitad de eso para un “control rápido”, tal vez lo parezca.

Andrea sugiere una configuración simple de cliente / servidor, pero me parece que podría fácilmente llamar una modificación muy leve de su script y mantener abierta la ventana de la consola mientras trabaja:

  • Llame al script, que realiza las importaciones y luego espera la entrada.
  • Minimice la ventana de la consola, cambie a su trabajo, lo que sea: * Do work *
  • Seleccione la consola de nuevo
  • Proporcionar el script con algún tipo de entrada
  • Recibe los resultados sin gastos generales de importación
  • Vuelva a alejarse de la secuencia de comandos mientras espera con gusto la entrada.

Supongo que su script es idéntico cada vez, es decir, no es necesario que le dé la ubicación de la stack de imágenes ni ningún comando en particular cada vez (¡pero estos también son fáciles de hacer!).

Ejemplo de RAAC’s_Script.py:

 import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation import scipy.ndimage import scipy.signal import sys import os print('********* RAAC\'s Script Now Running *********') while True: # Loops forever # Display a message and wait for user to enter text followed by enter key. # In this case, we're not expecting any text at all and if there is any it's ignored input('Press Enter to test image stack...') ''' * * **RAAC's Code Goes Here** (Make sure it's indented/inside the while loop!) * * ''' 

Para finalizar el script, cierre la ventana de la consola o presione ctrl + c.

Hice esto lo más simple posible, pero requeriría muy poco más para manejar cosas como dejarlo bien, hacer cosas ligeramente diferentes en función de la entrada, etc.