一、背景
GSON是Google提供的开源库,使用很便捷,但是在使用过程中也发现了其短板。在Bean类结构复杂时,进行反序列化耗时较长,尤其是很多在应用启动阶段需要反序列化一些内置的数据时,很让人头疼,通过抓Trace能发现这个性能问题。 注:本文基于Gson2.8.5分析(implementation ‘com.google.code.gson:gson:2.8.5’)
二、反序列化为什么耗时分析?
2.1 抛出问题:gson反序列化过程火焰图
如上图GSON解析过程可以看出,在反序列化过程中使用了大量反射导致耗时较长。 json结构:
{
"name":"zhang",
"age":33,
"sex":1,
"bestStudent":{
"name":"san",
"age":10,
"sex":1,
"grade":1,
"favoriteSubject":{
"subjectName":"music",
"subjectScore":90.1
},
"subjects":[
{
"subjectName":"music",
"subjectScore":90.1
},
{
"subjectName":"literature",
"subjectScore":80.1
},
{
"subjectName":"mathematics",
"subjectScore":70.1
}
]
},
"students":[
{
"name":"li",
"age":10,
"sex":1,
"grade":1,
"favoriteSubject":{
"subjectName":"music",
"subjectScore":90.1
},
"subjects":[
{
"subjectName":"music",
"subjectScore":90.1
},
{
"subjectName":"literature",
"subjectScore":80.1
},
{
"subjectName":"mathematics",
"subjectScore":70.1
}
]
},
{
"name":"wang",
"age":10,
"sex":1,
"grade":1,
"favoriteSubject":{
"subjectName":"literature",
"subjectScore":80.1
},
"subjects":[
{
"subjectName":"music",
"subjectScore":90.1
},
{
"subjectName":"literature",
"subjectScore":80.1
},
{
"subjectName":"mathematics",
"subjectScore":70.1
}
]
},
{
"name":"zhou",
"age":10,
"sex":1,
"grade":1,
"favoriteSubject":{
"subjectName":"music",
"subjectScore":90.1
},
"subjects":[
{
"subjectName":"music",
"subjectScore":90.1
},
{
"subjectName":"literature",
"subjectScore":80.1
},
{
"subjectName":"mathematics",
"subjectScore":70.1
}
]
}
]
}
2.2 Gson是怎么做反序列化的?
2.2.1 先看Gson构造函数,默认构造函数走到下面这个实现:
Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingStrategy,
final Map
boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle,
int timeStyle, List
List
List
this.excluder = excluder;
this.fieldNamingStrategy = fieldNamingStrategy;
this.instanceCreators = instanceCreators;
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
this.serializeNulls = serializeNulls;
this.complexMapKeySerialization = complexMapKeySerialization;
this.generateNonExecutableJson = generateNonExecutableGson;
this.htmlSafe = htmlSafe;
this.prettyPrinting = prettyPrinting;
this.lenient = lenient;
this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues;
this.longSerializationPolicy = longSerializationPolicy;
this.datePattern = datePattern;
this.dateStyle = dateStyle;
this.timeStyle = timeStyle;
this.builderFactories = builderFactories;
this.builderHierarchyFactories = builderHierarchyFactories;
// (1)
List
// built-in type adapters that cannot be overridden
factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
factories.add(ObjectTypeAdapter.FACTORY);
// the excluder must precede all adapters that handle user-defined types
factories.add(excluder);
// users' type adapters
factories.addAll(factoriesToBeAdded);
// type adapters for basic platform types
factories.add(TypeAdapters.STRING_FACTORY);
factories.add(TypeAdapters.INTEGER_FACTORY);
factories.add(TypeAdapters.BOOLEAN_FACTORY);
factories.add(TypeAdapters.BYTE_FACTORY);
factories.add(TypeAdapters.SHORT_FACTORY);
TypeAdapter
factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter));
factories.add(TypeAdapters.newFactory(double.class, Double.class,
doubleAdapter(serializeSpecialFloatingPointValues)));
factories.add(TypeAdapters.newFactory(float.class, Float.class,
floatAdapter(serializeSpecialFloatingPointValues)));
factories.add(TypeAdapters.NUMBER_FACTORY);
factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY);
factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY);
factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter)));
factories.add(TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter)));
factories.add(TypeAdapters.ATOMIC_INTEGER_ARRAY_FACTORY);
factories.add(TypeAdapters.CHARACTER_FACTORY);
factories.add(TypeAdapters.STRING_BUILDER_FACTORY);
factories.add(TypeAdapters.STRING_BUFFER_FACTORY);
factories.add(TypeAdapters.newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL));
factories.add(TypeAdapters.newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER));
factories.add(TypeAdapters.URL_FACTORY);
factories.add(TypeAdapters.URI_FACTORY);
factories.add(TypeAdapters.UUID_FACTORY);
factories.add(TypeAdapters.CURRENCY_FACTORY);
factories.add(TypeAdapters.LOCALE_FACTORY);
factories.add(TypeAdapters.INET_ADDRESS_FACTORY);
factories.add(TypeAdapters.BIT_SET_FACTORY);
factories.add(DateTypeAdapter.FACTORY);
factories.add(TypeAdapters.CALENDAR_FACTORY);
factories.add(TimeTypeAdapter.FACTORY);
factories.add(SqlDateTypeAdapter.FACTORY);
factories.add(TypeAdapters.TIMESTAMP_FACTORY);
factories.add(ArrayTypeAdapter.FACTORY);
factories.add(TypeAdapters.CLASS_FACTORY);
// type adapters for composite and user-defined types
factories.add(new CollectionTypeAdapterFactory(constructorConstructor));
factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));
this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor);
factories.add(jsonAdapterFactory);
factories.add(TypeAdapters.ENUM_FACTORY);
// (2)对业务Bean类的反序列化主要就是靠此TypeAdapterFactory创建的TypeAdapter实现的
factories.add(new ReflectiveTypeAdapterFactory(
constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));
this.factories = Collections.unmodifiableList(factories);
}
(1) 为了解析json字符串,针对不同类型的节点,使用了不同的TypeAdapterFactory(2) 对业务Bean类的反序列化主要就是靠ReflectiveTypeAdapterFactory创建的TypeAdapter实现的,也正是这个TypeAdapter构造的TypeAdapter使用了反射给目标bean字段赋值。
2.2.2 TypeAdapter的作用
public abstract class TypeAdapter
// 为 value写入一个 JSON 值(数组、对象、字符串、数字、布尔值或 null)。
public abstract void write(JsonWriter out, T value) throws IOException;
// 读取一个 JSON 值(数组、对象、字符串、数字、布尔值或 null)并将其转换为 Java 对象。返回转换后的对象。
public abstract T read(JsonReader in) throws IOException;
}
如上所示,TypeAdapter主要定义了供子类实现的write和read方法。
参考文章
【1】抖音 Android 性能优化系列:启动优化实践