Поток Python для предварительного импорта модулей - PullRequest
4 голосов
/ 15 января 2010

Я пишу приложение на Python в области научных вычислений. В настоящее время, когда пользователь работает с графическим интерфейсом и запускает новое физическое моделирование, интерпретатор немедленно импортирует несколько необходимых модулей для этого моделирования, таких как Traits и Mayavi. Эти модули тяжелые и их импорт занимает слишком много времени, и пользователь должен ждать ~ 10 секунд, прежде чем он сможет продолжить, что плохо.

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

Мне нужен отдельный поток, который будет импортировать модули асинхронно. Вероятно, это будет подкласс threading.Thread.

Вот пример использования:

importer_thread = ImporterThread()
importer_thread.start()

# ...

importer_thread.import('Mayavi')
importer_thread.import('Traits')
# A thread-safe method that will put the module name
# into a queue which the thread in an inifine loop

# ...

# When the user actually needs the modules:
import Mayavi, Traits
# If they were already loaded by importer_thread, we're good.
# If not, we'll just have to wait as usual.

Так вы знаете что-нибудь подобное? Если нет, есть ли у вас какие-либо предложения по поводу дизайна?

Ответы [ 4 ]

2 голосов
/ 15 января 2010

Почему бы просто не сделать это при запуске приложения?

def background_imports():
    import Traits
    import Mayavi

thread = threading.Thread(target=background_imports)
thread.setDaemon(True)
thread.start()
2 голосов
/ 15 января 2010

Проблема в том, что импорт должен быть завершен до того, как его можно будет использовать. В зависимости от того, когда они используются впервые, приложение все равно может блокироваться на 10 секунд, прежде чем оно все равно может запуститься. Гораздо эффективнее было бы профилировать модули и выяснить , почему они так долго импортируют.

1 голос
/ 15 января 2010

Общая идея хороша, но сеанс Python / GUI может не быть таким уж отзывчивым, пока фоновый поток уходит import; к сожалению, import неотъемлемо и неизбежно существенно «блокирует» Python (это не только GIL, есть специальная дополнительная блокировка для импорта).

Все еще стоит попробовать, поскольку может сделать вещи немного лучше - это также очень просто, поскольку Queue s по своей природе поточно-ориентированы и, кроме Queue s put и get, все, что вам нужно, это в основном __import__. Тем не менее, не удивляйтесь, если это не поможет, и вам по-прежнему нужна дополнительная поддержка.

Если у вас есть какой-то накопитель, который по своей природе очень быстрый, но с ограниченным пространством, например, «RAM-накопитель» или особенно твердотельный твердотельный накопитель, возможно, стоит сохранить необходимые пакеты в .tar.bz2 (или другом в виде архива) и распаковывает его на быстрый диск при запуске программы (по сути, это просто ввод-вывод, поэтому не будет плохо блокировать вещи - операции ввода-вывода быстро освобождают GIL - и также особенно легко делегировать подпроцесс, выполняющий tar xjf или тому подобное).

Если некоторая медлительность импорта вызвана огромным количеством .py/.pyc/.pyo файлов, стоит попробовать сохранить их (только в .pyc форме , , а не как .py) в zip-файле и импортировании оттуда (но это только помогает с накладными расходами ввода-вывода, в зависимости от вашей ОС, файловой системы и диска: не помогает с задержками из-за загрузки огромных DLL или выполнения код инициализации в пакетах во время загрузки, что, как я подозреваю, является более вероятной причиной медлительности).

Вы могли бы также рассмотреть возможность разделения приложения на multiprocessing - снова используя Очереди (но многопроцессорного типа) для связи - так, чтобы импорт и некоторые тяжелые вычисления делегировались нескольким вспомогательным процессам и, таким образом, делались асинхронными (это также может помочь в полной мере использовать несколько ядер одновременно). Я подозреваю, что это, к сожалению, может быть трудно организовать должным образом для задач визуализации (например, тех, которые вы, вероятно, выполняете с помощью Mayavi), но это может помочь, если у вас также есть некоторые пакеты и задачи «чисто тяжелых вычислений».

0 голосов
/ 15 января 2010

"пользователь работает с графическим интерфейсом и запускает новое физическое моделирование"

Не совсем понятно. Означает ли "работа с графическим интерфейсом" двойной щелчок? Двойной щелчок что? Некоторые приложения wxWidgets GUI? Или бездельничать?

Если это так, что означает «запуск новой симуляции физики»? Нажмите кнопку где-нибудь еще? Кнопка GUI, чтобы вызвать панель, где они пишут код? Или они импортируют сценарий, который они написали в автономном режиме?

Почему импорт происходит до начала симуляции? Сколько времени занимает симуляция? Что показывает графический интерфейс?

Я подозреваю, что есть способ намного, намного ленивее делать большой импорт. Но по описанию сложно определить, есть ли момент времени, когда импорт не так важен для пользователя.

Темы не очень помогают. Что помогает, так это переосмысление пользовательского интерфейса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...