Пользователь
0,0
рейтинг
4 июля 2014 в 18:02

Разработка → Быстрые аналоги популярных библиотек для Python

Так получилось, что несколько месяцев я пытался серьёзно использовать в качестве сервера, железку на ARM процессоре.
Об этом я писал тут и тут.
Производительности мне часто не хватало, и я находил и искал различные альтернативы, часто активно использующие C/C++. Парочка библиотек под катом.


Заранее прошу прощения если все уже знают об этом но я вот только недавно раскопал эти либы.

JSON


Вот куда сейчас без него? Для веб приложений это по сути основной формат. Сервер должен уметь быстро преобразовывать python структуры в JSON и отдавать браузерам или устройствам. Наверное большинство делают import json и у них всё замечательно…
А вот если надо в разы быстрее тогда встречайте ujson. Порядки ускорения можно глянуть по ссылке, но на ARM по сути использование ujson позволило сократить время запроса с нескольких секунд до <1 секунды. Синтаксис ujson аналогичен обычному json хотя и отсутствуют некоторые атрибуты (к примеру у меня не вышло повесить свой обработчик для преобразования datetime). Так же ujson совместим с python3 и я ни разу не натыкался на его глюки.
Если у вас в JSON много текста не на английском языке то крайне выгодно использовать параметр ensure_ascii=False для функции dumps. Дело в том, что по умолчанию текст кодируется в JSON при помощи \u нотации что приводит к 6-8 байтам на один символ, а так можно всё отдавать чисто в utf-8, что уменьшает отдаваемый JSON в 2 или 3 раза (даже если используется gzip).
Внимание: для обычного json ensure_ascii=False приводит к серьёзной потери производительности, для ujson возможно даже улучшение производительности или незначительное ухудшение.

FeedParser


Многие наверно использовали эту библиотеку для того что бы парсить RSS, ATOM и т.д. Её производительность и раньше меня напрягала, а теперь я вообще не мог ей нормально пользоваться, так как парсиниг одной RSS мог длится минуту. На помощь мне пришёл SpeedParser, он позволил сократить время разбора RSS до нескольких секунд. В целом по синтаксису он совместим с FeedParser но поведение сильно отличается. К примеру он не видит кастомные namespace или игнорит которых нету в его списке (который жёстко забит в либе). Для правки некоторых ошибок мы применили MonkeyPatching (увы).

GZIP


Нельзя использовать максимальные значения, а лучше крутиться вокруг коэффициента 5. Ниже уже на скорость начинает сильно влиять размер, а выше уже сильно замедляет формирование контента на отдачу. Найти для gzip аналог трудно (и легко подменить в системе) но есть совет — использовать его только на стороне nginx и не пытаться из python. В одном из тестовых проектов, я использовал gzip сжатие как middleware в python и перенос его в nginx позволило сократить нагрузку.

Frameworks


Чем меньше оверхеда тем лучше. Не пытайтесь разворачивать крупные фреймворки, они работать будут но уже на паре другой человек всё встанет колом. Разница между Pylons и Tornado на пустой странице 3 раза в пользу последнего.

Как то так.
Продолжение истории с чатом тут: habrahabr.ru/post/228703.

ЗЫ в тексте много жаргонизмов, простите но мне так приятнее писать.
ЗЫ2 ошибок скорее всего так же много, пишите в личку если найдёте.
@stalkerg
карма
73,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (9)

  • +4
    Какие библиотеки, какие аналоги, кого с кем сравниваете, о чем пост?
    В тех же Frameworks вы обидели пилоны с торнадо на пустом месте, но альтернативу не предложили (хотя пост про аналоги).
    Или же вы спрашиваете аналоги? Ну тогда хабр не для вопросов
    • +1
      json vs ujson (а по ссылке ещё сравнение с 4 либами), FeedParser vs SpeedParser. Pylons/Django vs Tornado(или ещё чего лёгкого) только в контексте оверхеда.
      Ну и в целом это заметка — ощущение от работы с медленным сервером, она больше собирательная. Просто личный опыт раскрываю… на более не претендую.
  • +2
    In [40]: import json
    
    In [41]: %timeit json.dumps(n, ensure_ascii=True)
    10000 loops, best of 3: 79 µs per loop
    
    In [42]: %timeit json.dumps(n, ensure_ascii=False)
    1000 loops, best of 3: 448 µs per loop
    
    
    • +1
      А могли бы вы, то же самое сделать с ujson? У меня ещё просто во весь рост встала проблема размера JSON (до 1.5 мегабайта, после всех мероприятий до 250кило убавил)
      • +1
        На том же самом наборе данных:

        In [52]: %timeit ujson.dumps(n, ensure_ascii=False)
        10000 loops, best of 3: 46.4 µs per loop
        
        In [53]: %timeit ujson.dumps(n, ensure_ascii=True)
        10000 loops, best of 3: 58.3 µs per loop
        
        • 0
          Вот… по этому я и не заметил этого. :) В ujson с ensure_ascii=False даже быстрее чем с ensure_ascii=True. А так как мы значительно уменьшаем размер JSON это даёт существенный выигрыш.

          Какой Python к слову и какой процессор?
          • 0
            2.7.5 (default, Mar 9 2014, 22:15:05)
            [GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)]

            Core i5 (2.5Ghz)
  • 0
    ujson действительно в разы быстрее, но помимо того, что он не поддерживает некоторые аттрибуты, он также не совсем корректно делает дампы некоторых типов, например результаты генераторов (у меня была с ними некоторая дискуссия и в конце концов они добавили мой патч, но все-равно остались некоторые проблемы). Учитывая, что их компанию купила EA, я не особо верю в будущее этой библиотеки (статистика на гитхабе поддерживает мои подозрения), так что мы просто остановились на том, чтобы патчить эту библиотеку локально, не дожидаясь пока они сделают поддержку тех фич, которые нам надо.
    • 0
      1. Я выше написал, что так же столкнулся с некоторыми ограничениями. Но в целом это всё равно лучше чем по сути ничего.
      2. Публикуйте все наработки на github так же на ujson это могло бы улучшить библиотеку хоть и в виде форка.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.