Ускорение частей существующего приложения Python с помощью PyPy или Shedskin
Я ищу, чтобы принести улучшения скорости в существующее приложение, и я ищу совет относительно моих возможных вариантов. Приложение написано на Python, использует wxPython и упаковано с py2exe
(я только ориентируюсь на платформы windows). Части приложения являются вычислительно интенсивными и выполняются слишком медленно в интерпретируемом Python. Я не знаком с C, поэтому перенос частей кода на другой язык не является для меня подходящим вариантом.
Итак, мой вопрос в основном состоит в том, есть ли у меня четкая картина из моих вариантов, как я изложу ниже, или я подхожу к этому с неправильной стороны?
- запуск с pypy: Сегодня я начал экспериментировать с Pypy - результаты захватывающие, в том, что я могу запускать большие части кода из интерпретатора pypy, и я вижу 5X+ улучшения скорости без изменений кода. Однако, если я правильно понимаю, (a) Pypy с поддержкой wxpython является все еще незавершенной работой , и (b) Я не могу скомпилировать его до exe для распределение в любом случае . Так что, если я не ошибаюсь, это похоже на запрет для меня? Нет никакого способа упаковать вещи так, чтобы их части были выполнены с помощью pypy?
- преобразование кода в RPython, перевод с помощью pypy Таким образом, следующий вариант, похоже, на самом деле переписывает части кода на ограниченный язык pypy, что кажется довольно большой работой. Но если я это сделаю, то части кода могут быть скомпилированы в исполняемый файл (?) и тогда я могу получить доступ к коду через ctypes (?).
- другие ограниченные варианты Shedskin, похоже, является популярной альтернативой здесь, это лучше соответствует моим требованиям? Другие варианты, по-видимому, Cpython, Psyco и Unladen, но все они заменены или больше не поддерживаются.
3 ответа:
Использование PyPy действительно исключает py2exe и подобные инструменты, по крайней мере, пока один не портирован (AFAIK нет активной работы над этим). Тем не менее, поскольку двоичные файлы PyPy не нужно устанавливать, вы можете обойтись более сложным дистрибутивом, который включает в себя как исходный код Python, так и двоичный файл PyPy+stdlib и использует небольшую оболочку (пакетный файл, исполняемый файл) для облегчения запуска. Я не могу комментировать, является ли WxPython на PyPy достаточно зрелым для использования, но, возможно, кто-то на pypy-dev, wxpython-dev или любой из IRC-каналов может дать рекомендацию, если вы опишете свою ситуацию.
Перевод вашего кода на RPython не кажется мне жизнеспособным. Набор инструментов перевода на самом деле не является инструментом для разработки общего назначения, и создание библиотеки dll C для встраивания/ctypes кажется нетривиальным. Кроме того, код RPython действительно является низкоуровневым, что делает ваш код Python достаточно ограниченным, может привести к перезаписи половины его.
Что касается других ограниченных опций: вы, кажется, путаете CPython (оригинальный интерпретатор Python, написанный на C) с помощью Cython (компилятор для языка, похожего на Python, который выдает код C, подходящий для модулей расширения CPython). Оба проекта активны. Я не очень хорошо знаком с Shedskin, но, похоже, это инструмент для разработки целых программ, практически не взаимодействующих с неограниченным кодом Python. Cython кажется гораздо более подходящим: хотя он требует аннотаций ручного типа и кода более низкого уровня для достижения действительно хорошей производительности, его тривиально использовать из Python: сама цель проекта-создание модулей расширения.
Я бы обязательно заглянул в Cython, я играл с ним немного и видел ускорения ~100x над чистым python. Используйте модуль профиля, чтобы сначала найти узкие места. Обычно петли-это самые большие шансы увеличить скорость при переходе на Cython. Вы также должны посмотреть, можно ли использовать операции массива/вектора в Numpy вместо циклов, если это так, что также может дать экстремальные повышения производительности. Например:
a = range(1000000) for i in range(len(a)): a[i] += 5
Медленно, очень медленно. С другой стороны:
a = numpy.arange(10000000) a = a +5
Быстро, очень быстро.