优化Gson反序列化
优化反序列化的最佳方法是什么?优化Gson反序列化
我目前使用标准的Gson.toJson和Gson.fromJson方法对一些复杂对象进行序列化和反序列化,如果可能的话我期望减少反序列化时间。
我的对象中最复杂的包含43个变量。
如果你想使用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的实例,看看所述JsonGsonManual
和JsonGsonDatabind
实施方式中,在the jvm-serializers project。 (注意:也可以在Gson API中使用树型模型,而不是流式API或数据绑定API,但它似乎没有提供任何比数据绑定更高的性能改进,例如,请参阅JsonGsonTree
。)
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.toJson
和Gson.fromJson
(我开始也和接通以后杰克逊)
Gson.toJson(object)
=>JsonMapper.INSTANCE.mapper().writeValueAsString(object)
Gson.fromJson(object, clazz)
=>JsonMapper.INSTANCE.mapper().readValue(jsonString, clazz);
的伟大的东西,在优化重要的JSON是保持所有数据在短短的一个级别。
如果一个对象有另一个对象作为它的领域,这一领域的另一个对象等等,每一个new
消耗多一点的时间来反序列化。如果对象的所有字段都有原始类型,则反序列化会更快一些。
杰克逊和格森仍然是最好的图书馆来帮助你。
fastJson是一个C#库... – melbic 2015-03-30 11:59:28