DevilKing's blog

冷灯看剑,剑上几分功名?炉香无需计苍生,纵一穿烟逝,万丈云埋,孤阳还照古陵

0%

mson 让json序列化更快

原文链接

可以发现Gson序列化占用了大部分的执行时间,从图2可以更直观地看到Gson.fromJson占用了61%的执行时间。分析Gson的源码可以发现,它在序列化时大量使用了反射,每一个field,每一个get、set都需要用反射,由此带来了性能问题。

减少反射

采用JSONObject的方式来做序列化,

简单且性能好的

采用AnnotationProcessor(注解处理器)的方式,找到有JsonType注解的bean来处理,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(fullClassName);
ClassModel classModel = new ClassModel().setModifier("public final").setClassName(simpleClassName);
......
JavaFile javaFile = new JavaFile();
javaFile.setPackageModel(new PackageModel().setPackageName(packageName))
.setImportModel(new ImportModel()
.addImport(elementClassName)
.addImport("com.meituan.android.MSON.IJsonObject")
.addImport("com.meituan.android.MSON.IJsonArray")
.addImport("com.meituan.android.MSON.exceptions.JsonParseException")
.addImports(extension.getImportList())
).setClassModel(classModel);

List<? extends Element> enclosedElements = element.getEnclosedElements();
for (Element e : enclosedElements) {
if (e.getKind() == ElementKind.FIELD) {
processFieldElement(e, extension, toJsonMethodBlock, fromJsonMethodBlock);
}
}
try (Writer writer = sourceFile.openWriter()) {
writer.write(javaFile.toSourceString());
writer.flush();
writer.close();
}

继续优化

当JSON数据量比较大时用JSONObject处理会比较慢,究其原因是JSONObject会一次性将字符串读进来解析成一个map,这样会有比较大的内存浪费和频繁内存创建。经过调研Gson内部的实现细节,发现Gson底层有流式的解析器而且可以按需解析,可以做到匹配上的字段才去解析。根据这个发现我们将我们IJSONObject和IJsonArray换成了Gson底层的流解析来进一步优化我们的速度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Friend object = new Friend();
reader.beginObject();
while (reader.hasNext()) {
String field = reader.nextName();
if ("id".equals(field)) {
object.id = reader.nextInt();
} else if ("name".equals(field)) {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
object.name = null;
} else {
object.name = reader.nextString();
}
} else {
reader.skipValue();
}
}
reader.endObject();

兼容性

兼容性主要体现在能支持的数据类型上,目前MSON支持了基础数据类型,包装类型、枚举、数组、List、Set、Map、SparseArray以及各种嵌套类型(比如:Map<String, Map<String, List<String[]>>>

结论上

兼容性上,mson最好

性能上,mson也较少耗时,Gson和fastjson的耗时相当