Оптимизация десериализации 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);

Ответ 5

Отличный материал, который имеет значение для оптимизации json, заключается в том, чтобы сохранить все данные только на одном уровне.

Если у объекта есть другой объект в качестве его поля, а в этом поле другой объект и т.д., Каждый new потребляет немного больше времени для десериализации. Если все поля вашего объекта имеют примитивные типы, десериализация будет немного быстрее.

Джексон и Гсон продолжают быть лучшей библиотекой, которая поможет вам.