【性能优化】GSON解性能瓶颈分析

【性能优化】GSON解性能瓶颈分析

一、背景

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> instanceCreators, boolean serializeNulls,

boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,

boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,

LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle,

int timeStyle, List builderFactories,

List builderHierarchyFactories,

List 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 factories = new ArrayList();

// 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 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 {

// 为 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 性能优化系列:启动优化实践

相关推荐

新华社报告揭秘美国认知战,殖人话术彻底崩盘!
365体育怎么打不开网址

新华社报告揭秘美国认知战,殖人话术彻底崩盘!

📅 07-06 👁️ 7337
SWF转GIF - 在线转换视频文件
365bet足球即时比分网

SWF转GIF - 在线转换视频文件

📅 07-30 👁️ 8548