一直以来使用Gson作为JSON <-> Java数据转换的工具,只是因为Gson很好的支持泛型、支持注解、很好的设计等。再加上Google的支持,一切变得美好。不过经过测试验证,新的JSON工具组件FastJSON,比Gson更好、更快 and 更强。看来是时候重构JSON帮助工具(参见曾经发表的《Java操作JSON的便捷工具类(Gson)》)了。
测试环境:普通4核PC、内存4G、自带的JDK1.6.0_27(默认设置)
测试工具:无(普通的循环测试,计算运行时间 - 已经足够)
测试类:
public class JavaBeanFJTest {
public static class ModuleBean implements Serializable {
private static final long serialVersionUID = 1L;
public ModuleBean() {
}
public ModuleBean(Integer id, String name, Date createTime) {
this.id = id;
this.name = name;
this.createTime = createTime;
}
@Expose
private Integer id;
@Expose
private String name;
@Expose
@Since(1.0)
@SerializedName("ctime")
private Date createTime;
@Expose
private Integer parentId;
@Expose
@Since(1.1)
private List<ModuleBean> subModules;
@JSONField
public Integer getId() {
return id;
}
@JSONField
public void setId(Integer id) {
this.id = id;
}
@JSONField
public String getName() {
return name;
}
@JSONField
public void setName(String name) {
this.name = name;
}
@JSONField(name="ctime", format="yyyy-MM-dd HH:mm:ss")
public Date getCreateTime() {
return createTime;
}
@JSONField(name="ctime", format="yyyy-MM-dd HH:mm:ss")
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@JSONField
public List<ModuleBean> getSubModules() {
return subModules;
}
@JSONField
public void setSubModules(List<ModuleBean> subModules) {
this.subModules = subModules;
}
@JSONField
public Integer getParentId() {
return parentId;
}
@JSONField
public void setParentId(Integer parentId) {
this.parentId = parentId;
}
@Override
public boolean equals(Object obj) {
if(obj == null) return false;
if(!(obj instanceof ModuleBean)) {
return false;
}
ModuleBean other = (ModuleBean)obj;
if(other.getId() == null || other.getName() == null) {
return false;
}
return getId().equals(other.getId()) && getName().equals(other.getName());
}
}
@Test
public void testDoJavabean() {
Date createTime = DateUtils.createDate(2011, 8, 20, 19, 0, 0);
ModuleBean mb1 = new ModuleBean(1, "module1", createTime);
ModuleBean mb2 = new ModuleBean(2, "module2", createTime);
ModuleBean sub1_1 = new ModuleBean(11, "sub_module1", createTime);
sub1_1.setParentId(mb1.getId());
ModuleBean sub2_2 = new ModuleBean(21, "sub_module2", createTime);
sub2_2.setParentId(mb2.getId());
LinkedList<ModuleBean> subModules1 = new LinkedList<ModuleBean>();
subModules1.add(sub1_1);
mb1.setSubModules(subModules1);
LinkedList<ModuleBean> subModules2 = new LinkedList<ModuleBean>();
subModules2.add(sub2_2);
mb2.setSubModules(subModules2);
long start = System.nanoTime();
String mb1_json = JSON.toJSONString(mb1);
long spendTime = System.nanoTime() - start;
System.out.println(String.format("初次执行FastJson JSON.toJSONString() 耗时:%s ns(%s ms)", spendTime,
(double)(spendTime / 1000000.0d)));
System.out.println(String.format("FastJson mb1_json: %s", mb1_json));
start = System.nanoTime();
String mb2_json = JSON.toJSONString(mb2);
spendTime = System.nanoTime() - start;
System.out.println(String.format("再次执行FastJson JSON.toJSONString() 耗时:%s ns(%s ms)", spendTime,
(double)(spendTime / 1000000.0d)));
System.out.println(String.format("FastJson mb2_json: %s", mb2_json));
assertNotNull(mb1_json);
assertNotNull(mb2_json);
start = System.nanoTime();
String mb1_gson = JSONUtils.toJson(mb1);
spendTime = System.nanoTime() - start;
System.out.println(String.format("初次执行Gson toJson 耗时:%s ns(%s ms)", spendTime,
(double)(spendTime / 1000000.0d)));
System.out.println(String.format("Gson mb1_gson: %s", mb1_gson));
start = System.nanoTime();
String mb2_gson = JSONUtils.toJson(mb2);
spendTime = System.nanoTime() - start;
System.out.println(String.format("再次执行Gson toJSON 耗时:%s ns(%s ms)", spendTime,
(double)(spendTime / 1000000.0d)));
System.out.println(String.format("Gson mb2_gson: %s", mb2_gson));
assertNotNull(mb1_gson);
assertNotNull(mb2_gson);
System.out.println("============ 开始测试 反向序列化 ============");
start = System.nanoTime();
ModuleBean mb1_obj_fj = JSON.parseObject(mb1_json, ModuleBean.class);
spendTime = System.nanoTime() - start;
System.out.println(String.format("初次执行FastJson JSON.parseObject() 耗时:%s ns(%s ms)", spendTime,
(double)(spendTime / 1000000.0d)));
assertNotNull(mb1_obj_fj);
start = System.nanoTime();
ModuleBean mb2_obj_fj = JSON.parseObject(mb2_json, ModuleBean.class);
spendTime = System.nanoTime() - start;
System.out.println(String.format("再次执行FastJson JSON.parseObject() 耗时:%s ns(%s ms)", spendTime,
(double)(spendTime / 1000000.0d)));
assertNotNull(mb2_obj_fj);
assertEquals(mb1_obj_fj.getSubModules().size(), 1);
assertEquals(mb2_obj_fj.getSubModules().size(), 1);
start = System.nanoTime();
ModuleBean mb1_obj_gs = JSONUtils.fromJson(mb1_gson, ModuleBean.class);
spendTime = System.nanoTime() - start;
System.out.println(String.format("初次执行Gson fromJson() 耗时:%s ns(%s ms)", spendTime,
(double)(spendTime / 1000000.0d)));
assertNotNull(mb1_obj_gs);
start = System.nanoTime();
ModuleBean mb2_obj_gs = JSONUtils.fromJson(mb2_gson, ModuleBean.class);
spendTime = System.nanoTime() - start;
System.out.println(String.format("再次执行Gson fromJson() 耗时:%s ns(%s ms)", spendTime,
(double)(spendTime / 1000000.0d)));
assertNotNull(mb2_obj_gs);
assertEquals(mb1_obj_gs.getSubModules().size(), 1);
assertEquals(mb2_obj_gs.getSubModules().size(), 1);
assertEquals(mb1_obj_gs.getSubModules().get(0), sub1_1);
assertEquals(mb2_obj_gs.getSubModules().get(0), sub2_2);
start = System.nanoTime();
for(int i = 0; i < 1000 * 1000; i++) {
mb1_json = JSON.toJSONString(mb1);
}
spendTime = System.nanoTime() - start;
System.out.println(String.format("执行FastJSON JSON.toJSONString() 1000000 次 耗时:%s ns(%s ms),平均耗时:%s ns(%s ms)", spendTime,
(double)(spendTime / 1000000.0d), (double)(spendTime / 1000000.0d), (double)(spendTime / 1000000000000.0d)));
start = System.nanoTime();
for(int i = 0; i < 1000 * 1000; i++) {
mb1_gson = JSONUtils.toJson(mb1);
}
spendTime = System.nanoTime() - start;
System.out.println(String.format("执行Gson toJson 1000000 次 耗时:%s ns(%s ms),平均耗时:%s ns(%s ms)", spendTime,
(double)(spendTime / 1000000.0d), (double)(spendTime / 1000000.0d), (double)(spendTime / 1000000000000.0d)));
}
}
测试结果:
初次执行FastJson JSON.toJSONString() 耗时:106010121 ns(106.010121 ms)
再次执行FastJson JSON.toJSONString() 耗时:272940 ns(0.27294 ms)
初次执行Gson toJson 耗时:214912510 ns(214.91251 ms)
再次执行Gson toJSON 耗时:1015771 ns(1.015771 ms)
============ 开始测试 反向序列化 ============
初次执行FastJson JSON.parseObject() 耗时:32923458 ns(32.923458 ms)
再次执行FastJson JSON.parseObject() 耗时:258134 ns(0.258134 ms)
初次执行Gson fromJson() 耗时:8330668 ns(8.330668 ms)
再次执行Gson fromJson() 耗时:994540 ns(0.99454 ms)
执行FastJSON JSON.toJSONString() 1000000 次 耗时:17250840540 ns(17250.84054 ms),平均耗时:17250.84054 ns(0.01725084054 ms)
执行Gson toJson 1000000 次 耗时:102781095922 ns(102781.095922 ms),平均耗时:102781.095922 ns(0.102781095922 ms)