Оптимизация десериализации Gson
Каков наилучший способ оптимизации десериализации?
В настоящее время я использую стандартные методы Gson.toJson и Gson.fromJson для сериализации и десериализации некоторых сложных объектов, и я стараюсь уменьшить время десериализации, если это возможно.
Самый сложный из моего объекта содержит 43 переменных, если это имеет значение.
Ответы
Ответ 1
Если вы хотите использовать Gson, а не переключиться на другой API-интерфейс Java-to/from-JSON, и если производительность автоматической записи данных Gson не будет достаточной, то можно остаться с API Gson и выжать некоторые из них умеренно улучшенная производительность.
В последних раундах тестов производительности, опубликованных на https://github.com/eishay/jvm-serializers/wiki, результаты показывают, что совместная производительность сериализации и десериализации Gson может быть улучшена примерно на 25%, используя потоковое API Gson вместо привязки данных.
Обратите внимание, что это в целом значительно усложняет реализацию кода пользователя, где решения, сопоставимые с однострочными new Gson().toJson(something)
использующие API new Gson().toJson(something)
данных, например new Gson().toJson(something)
, заменяются (легко) десятками строк, включая циклы и условные. Таким образом, стоимость улучшенной производительности - более сложный код.
Примеры использования API потоковой передачи по сравнению с API JsonGsonManual
JsonGsonDatabind
реализациях JsonGsonManual
и JsonGsonDatabind
в проекте jvm-serializers.
(Примечание. Можно также использовать древовидную модель в API Gson вместо API-интерфейсов потоковой передачи или привязки данных, но, похоже, он не предлагает каких-либо улучшений производительности по сравнению с привязкой данных. Например, см. JsonGsonTree
.)
Ответ 2
Нет способа улучшить время сериализации и десериализации библиотеки Gson.
Как сказал программист Брюс, если время выполнения действительно имеет для вас значение, взгляните на библиотеку Джексона. Он, на мой взгляд, немного более "сложен" в использовании, но он доказал свою эффективность намного быстрее, чем любые другие библиотеки json в тестах производительности.
Вот несколько советов по улучшению производительности с Джексоном.
Ответ 3
Gson известен и использует его для удобства использования. Если вам нужна скорость, вам придется взглянуть на супер популярного Джексона Джсона.
Я тестировал и сравнивал как Gson, так и Jackson, и я могу сказать вам, что в некоторых случаях Джексон в 15 раз быстрее и сериализации, и десериализации, даже на очень больших объектах.
Чтобы получить аналогичное поведение, как Json, я использую следующие настройки
public enum JsonMapper {
INSTANCE;
private final ObjectMapper mapper;
private JsonMapper() {
mapper = new ObjectMapper();
VisibilityChecker<?> visibilityChecker = mapper.getSerializationConfig().getDefaultVisibilityChecker();
mapper.setVisibilityChecker(visibilityChecker
.withFieldVisibility(Visibility.ANY)
.withCreatorVisibility(Visibility.NONE)
.withGetterVisibility(Visibility.NONE)
.withSetterVisibility(Visibility.NONE)
.withIsGetterVisibility(Visibility.NONE));
}
public ObjectMapper mapper() {
return mapper;
}
}
Это окажется для тех же самых строк json, что и Gson для тех же объектов. Вы можете настроить его, чтобы использовать только геттеры и сеттеры, если хотите. Я бы посоветовал вам прочитать обо всех аннотациях Jackson json для обработки подтипов (полезно для систем RPC-стиля).
Мои варианты использования: я использую jackson как сериализацию, когда мне нужно сохранять капли в системах хранения (Redis, Cassandra, Mongo,... иногда mysql тоже). Я также использую его как сериализацию для своих API-интерфейсов RPC для довольно высоких систем трафика, хотя я предпочитаю использовать Protobuf для тех, когда это возможно. В этом последнем случае я использую Jackson для непосредственного сериализации в байт [] или поток для повышения производительности.
Последнее примечание. Объект mapper является потокобезопасным и имеет один статический экземпляр, как в примере, который я только что представил, не позволит вам получить небольшие накладные расходы.
EDIT: Я знаю, что мой пример не соответствует многим лучшим практикам, указанным на странице Jackson, но это позволяет мне иметь простой для понимания код, который выглядит как Gson.toJson
и Gson.fromJson
(который я начал с тоже включился позже в Джексон)
Gson.toJson(object)
=> JsonMapper.INSTANCE.mapper().writeValueAsString(object)
Gson.fromJson(object, clazz)
=> JsonMapper.INSTANCE.mapper().readValue(jsonString, clazz);
Ответ 4
Я бы переключился на Джексона и рассмотрел другие решения намного быстрее, чем Gson в тестах.
Ответ 5
Отличный материал, который имеет значение для оптимизации json, заключается в том, чтобы сохранить все данные только на одном уровне.
Если у объекта есть другой объект в качестве его поля, а в этом поле другой объект и т.д., Каждый new
потребляет немного больше времени для десериализации. Если все поля вашего объекта имеют примитивные типы, десериализация будет немного быстрее.
Джексон и Гсон продолжают быть лучшей библиотекой, которая поможет вам.