java 提高gson的速度_Json解析速度比较-Android API、Gson、Fastjson

本文对比了Android中三种JSON解析库——Android API、Gson和Fastjson的性能。实验结果显示,谷歌的Gson在解析速度上表现出显著优势。Gson通过JsonObject类和内部的LinkedTreeMap实现高效解析,而Fastjson的原理类似但细节不同。文章提到了Gson利用反射和bean类的get/set方法进行赋值,强调了get和set方法的重要性。
摘要由CSDN通过智能技术生成

IOS现成的API里的json解析速度非常快,这里就不说了,今天对比一下Android里面json的解析库。

首先第一个是Android API里面自带的json解析,其次是谷歌提供的Gson解析库(开源),其次是在网上看到的解析很快速的阿里巴巴分享的Fastjson包。Android自带的json解析大家一定都很熟悉了,这里不介绍了,这里详细说说谷歌提供的另一套解析库Gson:

gson的使用方法非常的简单。只需要将需要解析的json字符串和对应的Bean类xing型传递给GSON类的from方法既可:Gson gson = new Gson();

List so = gson.fromJson(mJsonString, new

TypeToken>() {}.getType());

这里的beanlei类中的字段的命名要和json中的字段相同,其次实现get和set方法(稍后讲原因)。

标准的bean:import java.util.List;

public class Geo {

private String type;

private List coordinates;

public Geo() {}

public String getType() {

return type;

}

public void setType(String type) {

this.type = type;

}

public List getCoordinates() {

return coordinates;

}

public void setCoordinates(List coordinates) {

this.coordinates = coordinates;

}

}

我曾经担心复杂的json结构会不会解析出现问题,但是试验了以后嵌套了其他的bean类,照样迭代赋值了。

阿里巴巴提供的fastjson库使用方法和gson一样,只是底层的原理不同。这里不详细介绍了。

下面看一下三个库解析相同的json字段的对比:(使用了25条非常复杂的Json数据)

1B955A8EDA97DCDEA82EA01F4E785640_B500_900_390_739.PNG

大家可以看到谷歌提供的gson有非常大的速度优势。这里我们走进它的代码浏览一下。

找到了关键的类:JsonObject.java

package com.google.gson;

import com.google.gson.internal.LinkedTreeMap;

import java.util.Map.Entry;

import java.util.Set;

public final class JsonObject extends JsonElement

{

private final LinkedTreeMap members = new LinkedTreeMap();

JsonObject deepCopy()

{

JsonObject result = new JsonObject();

for (Map.Entry entry : this.members.entrySet()) {

result.add((String)entry.getKey(), ((JsonElement)entry.getValue()).deepCopy());

}

return result;

}

public void add(String property, JsonElement value)

{

if (value == null) {

value = JsonNull.INSTANCE;

}

this.members.put(property, value);

}

public JsonElement remove(String property)

{

return (JsonElement)this.members.remove(property);

}

public void addProperty(String property, String value)

{

add(property, createJsonElement(value));

}

public void addProperty(String property, Number value)

{

add(property, createJsonElement(value));

}

public void addProperty(String property, Boolean value)

{

add(property, createJsonElement(value));

}

public void addProperty(String property, Character value)

{

add(property, createJsonElement(value));

}

private JsonElement createJsonElement(Object value)

{

return value == null ? JsonNull.INSTANCE : new JsonPrimitive(value);

}

public Set> entrySet()

{

return this.members.entrySet();

}

public boolean has(String memberName)

{

return this.members.containsKey(memberName);

}

public JsonElement get(String memberName)

{

return (JsonElement)this.members.get(memberName);

}

public JsonPrimitive getAsJsonPrimitive(String memberName)

{

return (JsonPrimitive)this.members.get(memberName);

}

public JsonArray getAsJsonArray(String memberName)

{

return (JsonArray)this.members.get(memberName);

}

public JsonObject getAsJsonObject(String memberName)

{

return (JsonObject)this.members.get(memberName);

}

public boolean equals(Object o)

{

return (o == this) || (((o instanceof JsonObject)) && (((JsonObject)o).members.equals(this.members)));

}

public int hashCode()

{

return this.members.hashCode();

}

}

可以看到其中使用了一个LinkedTreeMap来缓存字段与值。这里要比我们直接使用API中的方法寻找要快,其次在类ProtoTypeAdapter.java中我们找到了赋值方法:@SuppressWarnings("unchecked")

@Override

public GeneratedMessage deserialize(JsonElement json, Type typeOfT,

JsonDeserializationContext context) throws JsonParseException {

try {

JsonObject jsonObject = json.getAsJsonObject();

Class extends GeneratedMessage> protoClass =

(Class extends GeneratedMessage>) typeOfT;

try {

// Invoke the ProtoClass.newBuilder() method

Object protoBuilder = getCachedMethod(protoClass, "newBuilder")

.invoke(null);

Class> builderClass = protoBuilder.getClass();

Descriptor protoDescriptor = (Descriptor) getCachedMethod(

protoClass, "getDescriptor").invoke(null);

// Call setters on all of the available fields

for (FieldDescriptor fieldDescriptor : protoDescriptor.getFields()) {

String name = fieldDescriptor.getName();

if (jsonObject.has(name)) {

JsonElement jsonElement = jsonObject.get(name);

String fieldName = name + "_";

Field field = protoClass.getDeclaredField(fieldName);

Type fieldType = field.getGenericType();

Object fieldValue = context.deserialize(jsonElement, fieldType);

Method method = getCachedMethod(

builderClass, "setField", FieldDescriptor.class, Object.class);

method.invoke(protoBuilder, fieldDescriptor, fieldValue);

}

}

// Invoke the build method to return the final proto

return (GeneratedMessage) getCachedMethod(builderClass, "build")

.invoke(protoBuilder);

} catch (SecurityException e) {

throw new JsonParseException(e);

} catch (NoSuchMethodException e) {

throw new JsonParseException(e);

} catch (IllegalArgumentException e) {

throw new JsonParseException(e);

} catch (IllegalAccessException e) {

throw new JsonParseException(e);

} catch (InvocationTargetException e) {

throw new JsonParseException(e);

}

} catch (Exception e) {

throw new JsonParseException("Error while parsing proto: ", e);

}

}

这里通过反射类的set方法来给变量赋值,因此bean类中的变量要加上get和set方法。

文章出处:  http://android-study.diandian.com/post/2013-07-11/40050907908

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值