由于工作上有json格式的数据需要处理, 需要一个json库, 但是网上的json库不是性能不好就是功能有限。 不得已逼自己动手写一个。 由于时间有限, 目前这个库只是用最基础的反射实现。 我打算分三个阶段完善这个jsonconvert库。
1、 json的框架与扩展性设计
2、 反序列化与序列化功能的优化
3、 性能优化,去掉反射改用asm
虽然目前是用反射实现的, 但是其性能已经不比其他json库差多少。 初期大部分时间花在框架与反序列化的设计上面。 实现细节方面没有下太多功夫。 现在将jsonconvert开源出来, 希望集思广益, 从网友那吸收更多的金点子~ : )
先让大家看看jsonconvert的性能是个什么程度, 如果性能不好, 相信大家也不会再往下看了。 最近看到iteye上面有个fastjson库, 性能算是目前最快的, 下面是与fastjson简单的性能比较结果: (测试代码见附件)
--------------------------NodeRecord-----------------------------------
jsonconvert 循环解析单例10000次耗时: 786
fastjson 循环解析单例10000次耗时: 1466
jsonconvert 循环解析数组10000次耗时: 13403
fastjson 循环解析数组10000次耗时: 27020
-----------------------------------------------------------------------
jsonconvert 循环序列单例10000次耗时: 867
fastjson 循环序列单例10000次耗时: 809
jsonconvert 循环序列数组10000次耗时: 16270
fastjson 循环序列数组10000次耗时: 13830
--------------------------SimpleRecord-----------------------------------
jsonconvert 循环解析单例10000次耗时: 349
fastjson 循环解析单例10000次耗时: 433
jsonconvert 循环解析数组10000次耗时: 3234
fastjson 循环解析数组10000次耗时: 6454
-------------------------------------------------------------------------
jsonconvert 循环序列单例10000次耗时: 240
fastjson 循环序列单例10000次耗时: 327
jsonconvert 循环序列数组10000次耗时: 3769
fastjson 循环序列数组10000次耗时: 3051
可以看出jsonconvert虽然是反射做的, 其性能已经不比fastjson差了。 而且如果测试的JavaBean内嵌层越多, 与fastjson的差距就会越大。 本来想用JDK7里面的InvokeDynamic替换反射, 但是考虑兼容JDK5、6, 且以后始终会用asm代替, 所以没有使用, 简单的测试过InvokeDynamic,性能只是比反射快1-2倍而已,与直接调用的差距还是有一段滴。
下面介绍一下jsonconvert的功能。 普通对象只需要使用一个类JsonConvert, 该类只有三个方法:
public static String convertTo(Object value);
public static <T> T convertFrom(String text, Class<T> clazz);
public static <T> T[] convertArrayFrom(String text, Class<T> clazz);
简单介绍下jsonconvert的功能,目前默认支持的类型:
boolean -- double
Boolean[]-- double[]
String
Enum
Collection
Map
树形循环引用(有空会重点介绍)
jsonconvert最大的特点是扩展性强。 含扩展类(有时间再写个详细的文档):
JsonListener : 单个字段类(根据一个字符串值就可以转换成的对象)
JsonObjectToken: 大对象类(以"{" 开头的对象)
JsonObjectPrinter 序列化类
由于时间有限, 下面只简单介绍下JsonListener :
Jsonconvert里面所有基础数据类型都是根据JsonListener 转换的。 大家可以看到很多java库里面都会把boolean、int、boolean[]、int[]、String 这些类进行特殊处理。 而jsonconvert里面秉着纯面向对象思想, 不会给boolean、int这些"异类"数据类型给予国企优待。与其他类型一视同仁。 库默认只实现了8个基本数值类型与String、枚举类。 很多其他常用类(如 Date, BigInteger, AtomicLong)并没有内置(后期可能会加上)。如果你当前有JavaBean的字段用到了Date类型, 你可以手工给jsonconvert注册Date的JsonListener:
import com.tencent.tendon.convert.json.*;
public class DateJsonListener implements JsonListener<Date> {
@Override
public String convertTo(Date value) {
return value == null ? null : String.valueOf(value.getTime());
}
@Override
public Date convertFrom(String value) {
return value == null ? null : new Date(Long.parseLong(value));
}
@Override
public boolean quotable() {
return true;
}
}
JsonFactory.register(java.util.Date.class, new DateJsonListener());
同时你可以更改框架里面的默认实现。 比如框架的里面的byte[] 字段的序列化得到的是[1,2,3] 这种类int[]字符串。 如果你想将byte[]转换成base64字符串输出可以给JsonFactory注册自己的byte[]对象的JsonListener:
JsonFactory.register(byte[].class, new JsonListener<byte[]>() {
@Override
public String convertTo(byte[] value) {
if (value == null) return null;
return JsonWriter.hexTo(value);
}
@Override
public byte[] convertFrom(String value) {
if (value == null) return null;
return JsonWriter.hexFrom(value);
}
@Override
public boolean quotable() {
return true;
}
});
jsonconvert库下载地址:
http://tendon.googlecode.com/svn/trunk/tendon.jsonconvert/tags/0.1.0-beta/
(待续)....