2013-03-19 212 views
9

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

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

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

回答

13

如果你想使用Gson,而不是切换到另一个Java到/从JSON API,并且如果Gson的automagic数据绑定的性能不够好,那么可以使用Gson API,并挤出一些适度好的表现。

https://github.com/eishay/jvm-serializers/wiki上发布的最新一轮性能测试中,结果表明Gson系列化和反序列化的组合性能可能会提高约25%,使用the streaming API of Gson代替数据绑定。请注意,这通常使用户代码的实现复杂化,其中与(例如)new Gson().toJson(something)的使用数据绑定API的单行程相比较的解决方案被替换为(容易)几十行,包括循环和条件。所以,改进性能的代价是更复杂的代码。

对于使用流API与数据绑定API的实例,看看所述JsonGsonManualJsonGsonDatabind实施方式中,在the jvm-serializers project。 (注意:也可以在Gson API中使用树型模型,而不是流式API或数据绑定API,但它似乎没有提供任何比数据绑定更高的性能改进,例如,请参阅JsonGsonTree。)

3

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

由于程序员布鲁斯说,如果执行时间真正的问题给你,看看在Jackson库。在我看来,使用起来更“复杂”一些,但它已经被证明比基准测试中的其他json库快得多。

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

+2

同意(显然)。我会补充一点,尽管Jackson的配置选项比Gson API的配置选项更广泛和重要,但对于需要最小定制处理的数据结构之间映射的简单用例,杰克逊像Gson一样提供了一个简单的线解决方案。 – 2013-03-22 19:35:26

3

Gson是众所周知的,因为它易于使用。如果你想要速度,你将不得不看看超人气杰克逊杰森。

我已经测试和基准都GSON和杰克逊,我可以告诉你,在一些使用情况杰克逊是快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为同一对象。如果你愿意,你可以将它设置为只使用getter和setter。我建议你阅读关于处理子类型的所有jackson json注释(对RPC风格的系统有用)。

我用例:我用杰克逊系列化,当我需要保存斑点存储系统(Redis的,卡桑德拉,蒙戈,...有时mysql的也行)。我还将它用作我的RPC风格API的序列化,用于相当高流量的系统,尽管我更喜欢在可能的情况下使用Protobuf。在这最后一种情况下,我使用Jackson直接序列化为byte []或流以获得更好的性能。最后

一个注意:对象映射器是线程安全的,有像我刚刚提交将阻止你有轻微的实例开销例如一个静态实例。

编辑:我知道我的例子并没有遵循杰克逊页面中指出的很多最佳实践,但它允许我有简单易懂的代码,看起来像Gson.toJsonGson.fromJson(我开始也和接通以后杰克逊)

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

0

的伟大的东西,在优化重要的JSON是保持所有数据在短短的一个级别。

如果一个对象有另一个对象作为它的领域,这一领域的另一个对象等等,每一个new消耗多一点的时间来反序列化。如果对象的所有字段都有原始类型,则反序列化会更快一些。

杰克逊和格森仍然是最好的图书馆来帮助你。