Подтвердить что ты не робот

Повышение скорости импорта модуля Python

Вопрос о том, как ускорить импорт модулей Python, был задан ранее (Ускорить загрузку python " загрузчика и Python - Speed ​​Up Imports?), но без конкретных примеров и не дал приемлемых решений. Поэтому я снова займусь проблемой, но на этот раз с конкретным примером.

У меня есть Python script, который загружает трехмерный стек с диска, сглаживает его и отображает его как фильм. Я вызываю это script из командной строки системы, когда хочу быстро просмотреть мои данные. Я в порядке с 700 мс, чтобы сгладить данные, поскольку это сопоставимо с MATLAB. Однако для импорта модулей требуется дополнительно 650 мс. Поэтому с точки зрения пользователя код Python работает на половине скорости.

Это серия модулей, которые я импортирую:

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

Конечно, не все модули одинаково медленны для импорта. Главными виновниками являются:

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

Я экспериментировал с использованием from, но это не так быстро. Поскольку Matplotlib является главным виновником, и он получил репутацию медленных обновлений экрана, я искал альтернативы. Один из них - PyQtGraph, но для импорта требуется 550 мс.

Я знаю одно очевидное решение, которое заключается в вызове моей функции из интерактивного сеанса Python, а не в командной строке системы. Это прекрасно, но это тоже MATLAB-like, я бы предпочел элегантность наличия моей функции в системной подсказке.

Я новичок в Python, и я не уверен, как это сделать. Поскольку я новичок, я ценю ссылки на то, как реализовать предлагаемые решения. В идеале, я ищу простое решение (не все мы!), Потому что код должен быть переносимым между несколькими компьютерами Mac и Linux.

4b9b3361

Ответ 1

вы можете создать простой сервер/клиент, сервер, постоянно выполняющий и обновляющий график, и клиент просто передает следующий файл для обработки.

Я написал простой пример сервера/клиента, основанный на базовом примере из документа socket docs: http://docs.python.org/2/library/socket.html#example

здесь 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()

и 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)

вы просто запускаете сервер:

python server.py

который выполняет импорт, тогда клиент просто отправляет через сокет имя файла нового файла для построения:

python client.py mytextfile.txt

то сервер обновляет график.

На моей машине выполняется импорт в течение 0,6 секунды при запуске client.py 0,03 секунды.

Ответ 2

Вместо этого вы можете импортировать свои модули, используя imp. См. здесь.

Например, import numpy as np, вероятно, может быть записано как

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

Это избавит python от просмотра всего вашего sys.path, чтобы найти нужные пакеты.

См. также:

Не удалось вручную импортировать gtk: модуль не найден

Ответ 3

1.35 секунд не длинный, но я полагаю, что если вы привыкли к половине того, что для "быстрой проверки", возможно, так кажется.

Andrea предлагает простую настройку клиента/сервера, но мне кажется, что вы можете так же легко вызвать небольшую модификацию своего script и оставить ее консольным окном открытым во время работы:

  • Вызовите script, который затем импортирует запрос
  • Свернуть окно консоли, переключиться на вашу работу, что угодно: * Делать работу *
  • Выберите консоль снова
  • Предоставьте script какой-нибудь ввод
  • Получать результаты без накладных расходов на импорт
  • Снова откройте script, пока он с радостью ждет ввода

Я предполагаю, что ваш script идентичен каждый раз, т.е. вам не нужно каждый раз указывать местоположение стека изображений или какие-либо конкретные команды (но это также легко сделать!).

Пример 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\ 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 ignored
    input('Press Enter to test image stack...')

    '''
    *
    *
    **RAAC Code Goes Here** (Make sure it indented/inside the while loop!)
    *
    *
    '''

Чтобы закончить script, закройте окно консоли или нажмите ctrl + c.

Я сделал это как можно более простым, но потребовалось бы очень немного дополнительного для того, чтобы обрабатывать такие вещи, как прекращение работы, делать несколько разные вещи на основе ввода и т.д.