原文链接
可以发现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的耗时相当