В одном из проектов потребовалось парсить достаточно объемные JSON файлы, отдаваемые API. Примерный размер файла 6 Мб и около 50000 записей. Стандартная библиотека работала достаточно неспешно и я решил сравнить производительность предлагаемых альтернатив.
Тестирование проводилось на виртуальной машине Ubuntu 10.10 32bit. Возможно, на 64 bit результаты будут отличаться. Время выполнения измерялось с помощью timeit.repeat(repeat=10, number=10) с последующим усреднением.
| Библиотека |
parsing |
parsing + serialization |
| simplejson |
2.162 |
5.182 |
| cjson |
2.395 |
7.851 |
| ujson |
2.416 |
5.524 |
| py-yajl |
3.830 |
Killed |
| jsonlib |
4.081 |
10.155 |
| json |
5.209 |
9.764 |
Как видите, самой быстрой реализацией на данный момент является simplejson. Следом за ним идут cjson и ujson. cjson немного быстрее при парсинге, но значительно проигрывает при сериализации обратно в строку. Все три библиотеки примерно в два раза быстрее стандартного модуля json.
py-yajl, несмотря на заверения авторов обертки, во-первых, оказалась значительно медленнее нативных библиотек, во-вторых, была достаточно сложна в сборке и установке, ну и в-третьих, выдала «killed» в качестве результата теста на парсинг-сериализацию.
Во время работы с библиотекой pingdjack от Ивана Сагалаева, обнаружилась досадная
особенность, не отраженная в документации, но доставившая мне немало хлопот.
Ввиду того, что в последних версиях django по умолчанию включена защита от CSRF,
система со включенным CSRFMiddleware выдает ошибку 403. Решить это можно двумя путями:
- отключением django.middleware.csrf.CsrfViewMiddleware в settings.py
- изменением кода pingdjack
Во втором варианте в файл server.py требуется добавить следующее:
# в начале файла
from django.views.decorators.csrf import csrf_exempt
# Добавить @csrf_exempt между @require_POST и def server_view
@require_POST
@csrf_exempt
def server_view(request, root='/'):
Второй метод выглядит предпочтительнее, т.к. маловероятно, что пингующий
сайт вдруг, внезапно, возьмет откуда-то требуемый CSRF-токен, а следовательно CSRF
защита для данного участка кода бессмысленна.
Когда я переписывал движок блога на django, мне захотелось получить список
популярных постов за последний месяц. Причем список должен был
строиться не по каким-то там эфемерным «плюсикам» к посту, а по количеству
просмотров. На помощь пришел Google Analytics с его мощным API и обертка
gdata для Python.
Итоговый код выглядит примерно так:
from django.core.urlresolvers import resolve, Resolver404
from datetime import date, timedelta
from blog.models import Entry # модель отвечающая за записи в блоге. Содержит поле popularity для хранения количества просмотров.
import gdata.analytics.service
import blog.views
client = gdata.analytics.service.AnalyticsDataService()
client.ClientLogin("user@gmail.com", "password")
# далее мы строим таблицу просмотров страниц по пути до данной страницы
data = client.GetData("ga:profileId", dimensions="ga:pagePath", metrics="ga:pageviews", start_date=(date.today() - timedelta(30)), end_date = date.today(), sort="-ga:pageviews")
for de in data.entry:
try:
view, args, kwargs = resolve(str(de.pagePath))
if view == blog.views.entry:
try:
e = Entry.objects.get(slug = kwargs["slug"])
e.popularity = int(str(de.pageviews))
e.save()
except Entry.DoesNotExist:
pass
except Resolver404:
pass
Если в не знаете своего ga:profileId, то можете получить его, выполнив следующий код:
import gdata.analytics.service
client = gdata.analytics.service.AccountsService()
client.ClientLogin('user@gmail.com', 'mypassword')
accounts = client.GetAccountList()
for account in accounts.entry:
print '%s profileId: %s' % (account.title.text, account.profileId)