Как мы увеличили скорость генерации JSON в 6000 раз

в 22:34, , рубрики: json, performance optimization, ruby, ruby on rails, ruby on rails 4, Блог компании Staply, метки: , ,
Краткий обзор способов формирования JSON

На сегодняшний день в Rails имеются следующие способы сериализации объектов в JSON:

  1. Вызов to_json() напрямую.
  2. RABL
  3. Active model serializers
  4. JBuilder


Первый способ идеально подходит для ситуаций, когда не требуется сериализовать вложенные объекты.

@posts.to_json(:include => [...], :methods => [...])

Однако, формируя JSON ответ со списком моделей, возникает необходимость сериализовать связанные модели в нужном виде.

JBuilder
По личному опыту, наиболее органично вписывающимся в Rails-разработку является, включенный по умолчанию в Rails 4, JBuilder.

json.extract! message, :id, :content, :chat_id
json.user do
    json.cache!(["user_", message.user_id]) do
      json.partial! 'users/user', user: message.user
    end
end

RABL
RABL, по сравнению с остальными гемами, представляется древним из-за синтаксиса и неповоротливым из-за низкой производительности монстром.

collection :@messages
attributes :id, :content, :chat_id
child(:user) { attributes :name }
node(:read) { |message| message.read_by?(@user) }

ActiveModel::Serializer
Active model serializers предлагает описывать JSON в виде ruby классов, без придуманного синтаксиса, что уменьшает зоопарк использования различных DSL в проекте.

Решение проблем с производительностью

Небольшое сравнение

Тестовые данные: 1000 типичных сообщений с отправителем и дополнительными полями.
JSON:

{
id: 1,
content: "Lorem",
chat_id: 1,
created_at: "2014-06-18T21:47:49.363Z",
kind: 0,
formatted_content: "<span>Lorem</span>",
user: {
    id: 1,
    name: "Ivan Petrov",
    image: "https://lh6.googleusercontent.com/photo.jpg"
},
files: [ ],
links: [ ]
}

to_json: 0.2ms
Oj: 0.1ms
JBuilder: 129.0ms
JBuilder with OJ: 88.0ms

Числа усреднены, но общая картина ясна. Сравнивать различные гемы между собой не имеет смысла, так как разница не существенна, но объективно, JBuilder является самым быстрым на сегодняшний день.
За удобство приходится платить скоростью. Все описанные гемы по скорости проигрывают методу to_json() в несколько раз.
Использование JBuilder без настройки будет стоить вам ~600.0ms

Существует несколько сопособов ускорить JBuilder:

  • Подключить гемы: oj, oj_mimic_json, multi_json.
    Добавить в инициализацию MultiJson.use(:oj)
    Что заменит стандартный сериализатор на более быстрый Oj.
  • Не использовать partials, существенно замедляющие JBuilder. Давно созданн issues, в котором, не смотря на закрытый статус, данная проблема фактически не решена
  • Кешировать шаблоны, используя встроенный в JBuilder метод cache!

В проекте Staply (почти открытая бета) мы использовали JBuilder, только на начальном этапе разработки, постепенно переходя на формирование JSON вручную при помощи to_json(). Что является оличной демонстрации всей концепции Rails, обеспечивающих довольно быструю и лёгкую разработку в начале с оптимизацией в конце.

Автор: maks_ohs

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js