优化Gson反序列化

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

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

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

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

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

请注意,这通常会使用户代码的实现变得非常复杂,其中与使用数据绑定API的单行程序相当的解决方案new Gson().toJson(something)例如, new Gson().toJson(something)被(容易)数十行代替,包括循环和条件句。 因此,改进性能的代价是更复杂的代码。

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

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

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

正如程序员布鲁斯所说,如果执行时间对你来说真的很重要,那么看看jackson图书馆吧。 在我看来,使用起来有点“复杂”,但事实certificate它比基准测试中的任何其他json库快得多。

以下是一些改善jackson表现的最佳做法。

Gson是众所周知的,并且易于使用。 如果你想要速度,你将不得不看看超级流行的jackson杰森。

我已经对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保存到存储系统时,我使用jackson作为序列化(Redis,Cassandra,Mongo,…有时也是mysql)。 我也将它用作我的RPC风格API的序列化,用于相当高的流量系统,尽管我更喜欢在可能的情况下使用Protobuf。 在最后一种情况下,我使用Jackson直接序列化为byte []或流以获得更好的性能。

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

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

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

我转投jackson ,并考虑fastJSON 。 在基准测试中,两者都显示出比Gson快得多。

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

如果一个对象有另一个对象作为它的字段,而这个字段有另一个对象等等,那么每个new对象都会消耗更多的时间进行反序列化。 如果对象的所有字段都具有基本类型,则反序列化将更快一些。

jackson和Gson一直是最好的图书馆来帮助你。