Блог Толика Вострякова

Живой опыт программирования, Python, Django, современные языки и немного фотографий
Блог - новые записи и ссылки (Atom)

Тестируем PyPy 1.2 с Джанго 1.2 -

Сегодня узнал о выпуске PyPy 1.2 и конечно сразу решил попробовать, что это такое :) Все эксперименты ниже проводил на MacBook Pro (Mac OS X Snow Leopard) с процессором 2.26Гц Intel Core 2 Duo и 2Гб памяти. Тесты производительности заявляли об ускорении работы Джанго в 2.86 раз. Проверим :)

Настройка работы Джанго

Скачал и поставил себе готовую версию под Mac OS X c JIT компилятором. Узнал, где у PyPy лежат сторонние библиотеки командой:

pypy -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"

и создал по этому пути simlink на директорию с библиотеками Python 2.6.4, чтобы не ставить все библиотеки заново под PyPy:

sudo ln -s /path/to/pypy/site-package/folder /path/to/python/site-package/folder

Для начала запустил pypy и импортировал Джанго: import django. Ошибок не возникло. Уже хорошо! Несколько других библиотек тоже импортировалось без ошибок: jinja2, html5lib, debug_toolbar, memcache и т.д. Следующим шагом, попробовал запустить свой блог под PyPy из папки проекта блога:

pypy manage.py runserver

Чудо не произошло, как и заявлено на сайте, PyPy не поддерживает CPython C API. Соответственно не работают библиотеки для работы с базами данных Postgersql и Mysql. Сервер не стартовал. Это пожалуй самое не достающее на данный момент в PyPy для его тестирования на реальных проектах. Второй недостаток: на данный момент поддерживается версия Питона 2.5.2

Ну ладно, попробуем все же сравнить скорость работы по сравнению с Python 2.6.4 без использования баз данных. Для этого я создал простой view (сразу с кодом замера скорости работы):

from datetime import datetime
import time

from django.shortcuts import render_to_response
from django.template import RequestContext

def test(request):
    start = time.time()

    tag = {'title': 'поиск по тэгу ...'}
    entries = [{'id': 1, 'status': 1, 'date': datetime.now(), 'title': 'Пост 1', 
                         'description': 'Мой первый пост в этом блоге'}]

    for i in xrange(1000):
        render_to_response('pypy/test.html', 
                           {'entries': entries, 'tag': tag}, 
                            RequestContext(request))

    end = time.time()
    print 'Time: %s' % (end - start)

    return render_to_response('pypy/test.html', 
                              {'entries': entries, 'tag': tag}, 
                              RequestContext(request))

Файл темплэйта pypy/test.html тоже достаточно простой, но тем не менее там используются тэги if, for и несколько фильтров: capfirst, date. Попробовал открыть страницу, генерируемую данным view. Упало, с показом стандартной страницы ошибки джанго. Эта же страница нормально открылась под Python 2.6.4. Поразбиравшись в чем проблема обнаружил, что дело всего ли в одной строке кода в коде поиска загрузчика темплэйтов в Джанго:

if hasattr(loader, '__iter__'):

После комментирования этого кода в Джанго (по иронии судьбы это как раз новый код кэширования загрузки темплэйтов, появившийся в Джанго 1.2) страница нормально открылась. Завел баг в баг-трекере проекта PyPy и буквально через несколько минут баг закрыли, так как это оказался дубликат уже заведенного бага #354. В следующей версии будет поправлено. Оперативно, что радует.

Замеры скорости

Время открытия страницы получилось интересным (привожу среднее значение):

PyPy 1.2:
7.5 секунды

Python 2.6.4:
4.65 секунды

Возможно это из-за того что, Python 2.6.4 работает в 64-битном режиме, а PyPy в режиме эмуляции 32-битного режиме, но скорость получилась почти в два раза медленнее. Наблюдение за потребляемой PyPy памятью показало, что при запуске джанго-сервера под PyPy сразу после запуска съедается около 38 Мб, после многокрастного открытия тестовой страницы в браузере расход памяти возрастает до 70 Мб. Что тоже в несколько раз больше, чем у Python 2.6.4.

Выводы

Для реального использования пока не подходит, но тем не менее ребята просто герои, что делают этот проект на полном энтузиазме в свое свободное время. Обязательно пожертвую проекту 5-10 евро, как разберусь со своим аккаунтом в PayPal (кнопка Donate есть на центральной странице проекта справа). Считаю, что нужно поддерживать такие проекты, если хотим в будущем увидеть развитие языка Python.

Дополнение

Покопавшись, нашел решение для подключение библиотек, использующих CPython C API, в частности для библиотек работы с базами данных. Решение описано в блоге PyPy. Делаем все по инструкции, кроме накатывания патча, это нужно только для PyQt. Запускаем rpyc сервер в отдельном окне:


python rpyc/servers/classic_server.py

Потом для каждой библиотеки, которая у нас не запускается в папке /path/to/PyPy/pypy/lib/ создаем питоновский файл, который называется, как библиотека. Например, для библиотеки работы с Mysql: MySQLdb.py. В файл добавляем всегда одно и тоже содержимое:


from _rpyc_support import proxy_module

proxy_module(globals())
del proxy_module

После этого импорт данной библиотеки начинает работать, правда скорее работать это будет очень медленно.

Дополнение: Мой патч включили в Джанго 1.2 и теперь джанговские темплэйты работают с PyPy 1.2!

Комментарии: 4

homa - 14.03.2010

что делают этот проект на полном энтузиазме в свое свободное время.
конечно не считая многих тысяч $K которые им грантуют.

kostia.lopuhin - 14.03.2010 Интересно!

А вы не пробовали использовать sqlite3? как я понимаю, pypy должен ее поддерживать http://pypy.org/compat.html - (written in pure python). Только вот у меня что-то не получилось...

Из того, что тестировал сам, вынес что pypy свертки обрабатывает раза в 2 медленнее, чем аналогичные циклы.
Толик Востряков - 14.03.2010 Нет, не пробовал, так как не применяю его в своих проектах, но получиться должно, так как в состав PyPy 1.2 входит своя версия sqlite3. Во-вторых, в конце поста в разделе "Дополнение" описано как подключить библиотеки, которые сразу не заработали с PyPy, правда это медленный вариант, только для экспериментов.
kostia.lopuhin - 14.03.2010 О, получилось наконец заставить работать с sqlite, в моем случае нужно было немного поправить код загрузки библиотеки в pypy/lib/sqlite3/dbapi2.py. Но пока оказывается, что оно раза в 2-3 медленнее, эх... может надо как-то по-другому мерить)

Добавить комментарий:


Буду использовать, только для связи с тобой

Чтобы и другие могли узнать о тебе

Вы можете использовать markdown разметку.

Например:
**жирный**
*курсив*
## Заголовок

Не используйте html-тэги. Все ссылки станут активными, все переводы строк будут заменены на <br>
captcha