java 优化 Gson 反序列化

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15509544/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 19:51:10  来源:igfitidea点击:

Optimizing Gson deserialization

javajsongson

提问by HandlerExploit

What is the best way to optimize deserialization?

优化反序列化的最佳方法是什么?

I am currently using the standard Gson.toJson and Gson.fromJson methods for serialization and deserialization of some complex objects and I am looking to reduce deserialization time if its possible.

我目前正在使用标准的 Gson.toJson 和 Gson.fromJson 方法对一些复杂对象进行序列化和反序列化,如果可能的话,我希望减少反序列化时间。

The most complex of my object contains 43 variables if that matters.

如果重要的话,我的对象中最复杂的包含 43 个变量。

回答by Programmer Bruce

If you want to use Gson, and not switch to another Java-to/from-JSON API, and if the performance of Gson's automagic databinding isn't good enough, then it is possible to stay with the Gson API, and squeeze out some moderately better performance.

如果你想使用Gson,而不是切换到另一个Java-to/from-JSON API,并且如果Gson的自动数据绑定性能不够好,那么可以继续使用Gson API,挤出一些适度更好的性能。

In the latest rounds of performance tests posted at https://github.com/eishay/jvm-serializers/wiki, the results suggest that the combined performance of Gson serialization and deserialization could possibly be improved by about 25%, by using the streaming API of Gsoninstead of databinding.

https://github.com/eishay/jvm-serializers/wiki 上发布的最新几轮性能测试中,结果表明 Gson 序列化和反序列化的组合性能可能会提高约 25%,通过使用流Gson 的 API而不是数据绑定。

Note that this generally significantly complicates the implementation of the user code, where solutions comparable to one-liners using the databinding API, e.g., new Gson().toJson(something), are replaced with (easily) dozens of lines, including loops and conditionals. So, the cost of the improved performance is more complicated code.

请注意,这通常会使用户代码的实现显着复杂化,其中类似于使用数据绑定 API 的单行程序的解决方案,例如 ,new Gson().toJson(something)被(轻松)替换为数十行,包括循环和条件。所以,提高性能的代价是更复杂的代码。

For examples of using the streaming API versus the databinding API, take a look at the JsonGsonManualand JsonGsonDatabindimplementations, in the jvm-serializers project.

有关使用流 API 与数据绑定 API 的示例,请查看jvm-serializers 项目中的JsonGsonManualJsonGsonDatabind实现。

(Note: One could also use the tree-model in the Gson API, instead of the streaming or databinding APIs, but it doesn't appear to offer any performance improvements over databinding. For an example, see JsonGsonTree.)

(注意:也可以在 Gson API 中使用树模型,而不是流或数据绑定 API,但它似乎没有提供任何比数据绑定的性能改进。例如,请参阅 参考资料JsonGsonTree。)

回答by Padrus

There is no way to improve the Gson library serialization and deserialization time.

没有办法改善Gson库的序列化和反序列化时间。

As Programmer Bruce said, if the execution time really matters to you, take a look at the Hymansonlibrary. It is, in my opinion, a little bit more "complicated" to use but it has been proven much faster than any other json libraries in benchmarks.

正如程序员布鲁斯所说,如果执行时间对您来说真的很重要,请查看Hymanson库。在我看来,使用起来有点“复杂”,但在基准测试中它已被证明比任何其他 json 库都要快得多。

Hereare some best practices to improve performances with Hymanson.

以下是改善 Hymanson 性能的一些最佳实践。

回答by le-doude

Gson is known and use for it's ease of use. If you want speed you will have to look at the super popular Hymanson Json.

Gson 因其易用性而广为人知并被使用。如果您想要速度,则必须查看超级流行的 Hymanson Json。

I have tested and benchmarked both Gson and Hymanson and I can tell you that in some use cases Hymanson is 15 times faster on both serialization and deserialization, even on very big objects.

我已经对 Gson 和 Hymanson 进行了测试和基准测试,我可以告诉你,在某些用例中,Hymanson 在序列化和反序列化方面的速度快 15 倍,即使在非常大的对象上也是如此。

To get similar behavior as Json I use the following settings

为了获得与 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;
    }
}

This will turn out to give the exact same json strings as Gson for the same objects. You can set it to use only getters and setters if you want to. I'd advise you to read about all the Hymanson json annotations for handling subtypes (useful for RPC-style systems).

这将证明为相同的对象提供与 Gson 完全相同的 json 字符串。如果需要,您可以将其设置为仅使用 getter 和 setter。我建议您阅读有关处理子类型的所有 Hymanson json 注释(对 RPC 样式系统有用)。

My use cases : I use Hymanson as serialization when I need to save blobs to storage systems (Redis, Cassandra, Mongo, ... sometime mysql too). I also use it as the serialization for my RPC-style APIs for fairly high traffic systems, although I prefer using Protobuf for those when possible. In this last case I use Hymanson to directly serialize to byte[] or stream for better performance.

我的用例:当我需要将 blob 保存到存储系统(Redis、Cassandra、Mongo ......有时也是 mysql)时,我使用 Hymanson 作为序列化。我还使用它作为我的 RPC 样式 API 的序列化,用于相当高流量的系统,尽管我更喜欢在可能的情况下使用 Protobuf。在最后一种情况下,我使用 Hymanson 直接序列化到 byte[] 或流以获得更好的性能。

One last note : The object mapper is thread safe and having one static instance like in the example I just submitted will prevent you from having the slight instantiation overhead.

最后一点:对象映射器是线程安全的,并且像我刚刚提交的示例中那样拥有一个静态实例将防止您有轻微的实例化开销。

EDIT : I am aware that my example doesn't follow a lot of the best practices pointed out in the Hymanson page but it allows me to have simple to understand code that looks like the Gson.toJsonand Gson.fromJson(which I started with too and switched on later to Hymanson)

编辑:我知道我的示例没有遵循 Hymanson 页面中指出的许多最佳实践,但它使我可以拥有简单易懂的代码,看起来像Gson.toJsonand Gson.fromJson(我也开始使用,后来又打开了Hyman逊)

Gson.toJson(object)=> JsonMapper.INSTANCE.mapper().writeValueAsString(object)Gson.fromJson(object, clazz)=> JsonMapper.INSTANCE.mapper().readValue(jsonString, clazz);

Gson.toJson(object)=> JsonMapper.INSTANCE.mapper().writeValueAsString(object)Gson.fromJson(object, clazz)=>JsonMapper.INSTANCE.mapper().readValue(jsonString, clazz);

回答by Moesio

The great stuff that matter in optimization for json is to keep all data in just one level.

json 优化中最重要的事情是将所有数据保持在一个级别。

If an object have another object as its field, and this field another object and so on, every newconsume a little more time to deserialization. If all fields of your object have primitive types, deserialization will be a bit faster.

如果一个对象有另一个对象作为它的字段,而这个字段又是另一个对象,依此类推,每new一个都会多花一点时间去反序列化。如果对象的所有字段都具有原始类型,反序列化会快一些。

Hymanson and Gson keep being the best library to help you.

Hymanson 和 Gson 一直是帮助您的最佳库。