Быстро реагирующие сценарии командной строки - PullRequest
4 голосов
/ 18 декабря 2010

Я некоторое время писал сценарии Python для командной строки, но в последнее время я чувствовал себя очень расстроенным из-за скорости.

Я не обязательно говорю о скорости обработки, диспетчеризации задач или других процессах, специфичных для инструментов командной строки (обычно это проблема проектирования / реализации), но я скорее говорю о простом запуске инструмента для вызова меню справки. или отображать минимальную информацию.

В качестве примера, Mercurial находится на отметке 0,080scs, а GIT на уровне 0,030scs

Я изучил исходный код Mercurial (в конце концов, это Python), но ответ на наличие быстродействующего скрипта все еще ускользает от меня.

Я думаю imports, и то, как вы управляете ими, является большой причиной для начальных замедлений. Но есть ли лучшая практика для быстрых, быстро реагирующих скриптов командной строки в Python?

Один скрипт Python, который импортирует os и optparse и выполняет main () для анализа некоторых параметров аргумента, занимает на моей машине 0,160scs только для отображения меню справки ...

Это в 5 раз медленнее, чем просто запуск git!

Edit:

Я не должен был упоминать git, как он написан на C. Но часть Mercurial все еще стоит, и нет, pyc не кажется большим улучшением (по крайней мере, мне).

Редактировать 2:

Хотя ленивый импорт - ключ к ускорению в Mercurial, он ключ к замедлению обычные скрипты Python не имеют автоматически генерируемых скриптов с pkg_resources, например:

from pkg_resources import load_entry_point

Если у вас есть сгенерированные вручную сценарии, которые не используют pkg_resources, вы должны увидеть увеличение скорости как минимум в 2 раза.

Тем не менее! Имейте в виду, что pkg_resources предоставляет хороший способ зависимости версий, поэтому убедитесь, что вы знаете, что его использование в основном означает возможные конфликты версий.

Ответы [ 2 ]

7 голосов
/ 18 декабря 2010

В дополнение к компиляции файлов Python, Mercurial изменяет импорт по требованию, что действительно сокращает время запуска.Он устанавливает __builtin__.__import__ для своей собственной функции импорта в модуле requireimport.

Если вы посмотрите на скрипт hg в / usr / lib / (или где бы он ни находился на вашем компьютере), вы можете увидеть это самив следующих строках:

try:
    from mercurial import demandimport; demandimport.enable()
except ImportError:
    import sys
    sys.stderr.write("abort: couldn't find mercurial libraries in [%s]\n" %
                     ' '.join(sys.path))
    sys.stderr.write("(check your install and PYTHONPATH)\n")
    sys.exit(-1)

Если вы измените строку импорта по требованию на pass, вы обнаружите, что время запуска существенно увеличивается.На моей машине, кажется, примерно вдвое.

Я рекомендую изучить requireimport.py, чтобы узнать, как применить подобную технику в ваших собственных проектах.

PS Git, как я уверен, вы знаете, написан на C, поэтому я не удивлен, что он быстро запускается.

0 голосов
/ 18 декабря 2010

Прошу прощения, но, конечно, вас не беспокоят 0,08 секунды. Несмотря на то, что вы не говорите это, вы чувствуете, что запускаете сценарий "внешней" оболочки (или другого языка), который вызывает несколько сотен скриптов Python внутри цикла - Это единственный способ, которым эти времена запуска могут иметь какое-либо значение. Итак, либо скрываете эту важную информацию в вашем вопросе, либо ваш отец этот парень .

Итак, предположим, что у вас есть внешние сценарии, вызывающие порядок сотен процессов Python: напишите этот внешний сценарий на Python и импортируйте все необходимое для Python в тот же процесс и запустите его оттуда. Поэтому вы будете сокращать запуск интерпретатора и импорт модуля для каждого выполнения скрипта.

Это относится даже к ртути, например. Вы можете импортировать «mercurial» и соответствующие подмодули и вызывать функции внутри него, которые выполняют те же действия, что и эквивалентные аргументы командной строки

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