Skip to content
gqlxj1987's Blog
Go back

mson 让json序列化更快

Edit page

原文链接

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

减少反射

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

简单且性能好的

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

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底层的流解析来进一步优化我们的速度

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的耗时相当


Edit page
Share this post on:

Previous Post
延迟队列
Next Post
数学小tips