有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java优化Gson反序列化

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

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

我的对象中最复杂的部分包含43个变量


共 (5) 个答案

  1. # 1 楼答案

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

    如果一个对象有另一个对象作为它的字段,而这个字段有另一个对象,依此类推,那么每new一次反序列化都会花费多一点时间。如果对象的所有字段都有基元类型,则反序列化速度会快一点

    杰克逊和格森一直是帮助你的最好的图书馆

  2. # 2 楼答案

    Gson因其易用性而闻名和使用。如果你想要速度,你必须看看超级流行的Jackson Json

    我已经对Gson和Jackson进行了测试和基准测试,我可以告诉您,在某些用例中,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;
        }
    }
    

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

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

    最后一点注意:对象映射器是线程安全的,具有一个静态实例(如我刚才提交的示例中所示)将防止您产生轻微的实例化开销

    编辑:我知道我的示例没有遵循jackson页面中指出的许多最佳实践,但它允许我拥有简单易懂的代码,看起来像Gson.toJsonGson.fromJson(我也是从这开始的,后来又转到jackson)

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

  3. # 3 楼答案

    如果您想使用Gson,而不是切换到另一个Java到JSON API或从JSON API切换到另一个Java,并且如果Gson的automagic数据绑定的性能不够好,那么可以继续使用Gson API,并挤出一些稍好的性能

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

    请注意,这通常会使用户代码的实现变得非常复杂,与使用数据绑定API的一行程序类似的解决方案(例如,new Gson().toJson(something))会被(轻松地)几十行(包括循环和条件)所取代。因此,提高性能的代价是更复杂的代码

    有关使用流式API与数据绑定API的示例,请查看the jvm-serializers project中的^{}^{}实现

    (注意:我们也可以在Gson API中使用树模型,而不是流式或数据绑定API,但它似乎没有提供任何比数据绑定更好的性能。例如,请参见^{}。)

  4. # 4 楼答案

    没有办法提高Gson库的序列化和反序列化时间

    正如程序员Bruce所说,如果执行时间对您来说真的很重要,那么看看Jackson库。在我看来,它的使用有点“复杂”,但事实证明它比基准测试中的任何其他json库都要快得多

    Here是一些改善杰克逊表现的最佳实践