一、背景
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<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle,
int timeStyle, List<TypeAdapterFactory> builderFactories,
List<TypeAdapterFactory> builderHierarchyFactories,
List<TypeAdapterFactory> factoriesToBeAdded) {
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<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
// 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<Number> longAdapter = longAdapter(longSerializationPolicy);
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<T> {
// 为 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 性能优化系列:启动优化实践