论坛首页 Java企业应用论坛

吹牛:我写的JSONParser可能是这个星球上最快了(Java)

浏览 143838 次
该帖已经被评为精华帖
作者 正文
   发表时间:2011-01-08   最后修改:2011-01-08
又签出测了一下,速度提高不少,特别是今天那个特别慢的问题解决了,时间类型也可以了。
从json-lib到jsontools、gson、jackson,目前来看jackson最好用最快,期待fastjson发布正式版,把我现在用的jackson替换掉。
0 请登录后投票
   发表时间:2011-01-09  
wenshao 写道
日期的序列化,目前不同的json processor的实现都是不一样的,如下:

  • fastjson : new Date(1294408029033)
  • jackson : 1294408029033
  • simplejson : Fri Jan 07 21:47:09 CST 2011
  • json-lib : {"date":7,"day":5,"hours":21,"minutes":47,"month":0,"seconds":9,"time":1294408029033,"timezoneOffset":-480,"year":111}
  • gson : "2011-1-7 21:47:09"


目前fastjson采用支持new Date()和long两个格式输出,也可以自定义。大家有什么建议么?

simplejson在日期的序列化是乱来的,json-lib也是乱来的。gson的方式倒是可以考虑直接支持的(目前可以通过扩展支持)。


new Date()的方式是否不标准呢? 至少ECMAScript5的JSON.parse会抛异常
建议支持ISO8601的格式yyyy-MM-ddThh:mm:ss.SSSZ
无论是JodaTime还是ECMAScript5都有良好的支持,应该是日期格式标准的一个趋势
0 请登录后投票
   发表时间:2011-01-09  
@厌倦发呆

你的建议很好的,这是我没想到的。但是我不打算把它当作缺省实现,而是一个支持的特性。
0 请登录后投票
   发表时间:2011-01-09  
wenshao 写道
@厌倦发呆

你的建议很好的,这是我没想到的。但是我不打算把它当作缺省实现,而是一个支持的特性。


顺便提一下,如果用long作为默认实现的话,有一个轻微的跨平台问题,据我的印象,不同语言平台对日期和long的转换的定义有所不同,有的是以millisecond为单位的,有的是以nanosecond为单位的,还有的是以tick为单位的,并且起始时点的选取也有所不同,如fantom语言的标准库就是以2000-01-01T00:00:00UTC为起始时点的。
不过这个问题不严重,只要对转换的long值有一个标准定义,解析的时候转换一下就好。
0 请登录后投票
   发表时间:2011-01-09   最后修改:2011-01-09
long作为默认实现,而且明确是millis。刚才实现了序列化支持ISO8601,parser的实现还未做。

如下:
// 带毫秒
StringWriter out = new StringWriter();

JSONSerializer serializer = new JSONSerializer();
serializer.config(Feature.UseISO8601DateFormat, true);
Assert.assertEquals(true, serializer.isEnabled(Feature.UseISO8601DateFormat));
serializer.write(out, new Date(1294552193254L));

Assert.assertEquals("2011-01-09T13:49:53.254", out.toString());


//不带毫秒
StringWriter out = new StringWriter();

JSONSerializer serializer = new JSONSerializer();
serializer.config(Feature.UseISO8601DateFormat, true);
Assert.assertEquals(true, serializer.isEnabled(Feature.UseISO8601DateFormat));
serializer.write(out, new Date(1294552193000L));

Assert.assertEquals("2011-01-09T13:49:53", out.toString());


//不带时间
StringWriter out = new StringWriter();

JSONSerializer serializer = new JSONSerializer();
serializer.config(Feature.UseISO8601DateFormat, true);
Assert.assertEquals(true, serializer.isEnabled(Feature.UseISO8601DateFormat));
serializer.write(out, new Date(1294502400000L));

Assert.assertEquals("2011-01-09", out.toString());
0 请登录后投票
   发表时间:2011-01-09  
wtusmchen 写道
又签出测了一下,速度提高不少,特别是今天那个特别慢的问题解决了,时间类型也可以了。
从json-lib到jsontools、gson、jackson,目前来看jackson最好用最快,期待fastjson发布正式版,把我现在用的jackson替换掉。


正式版的发布,最早在春节前,最晚2月底。谢谢支持 
0 请登录后投票
   发表时间:2011-01-09   最后修改:2011-01-09
parser也支持ISO8601的日期格式了,不过不是缺省支持的。如下:

场景1:
java.util.Date date = JSON.parseObject("2011-01-09T13:49:53", java.util.Date.class, Feature.AllowISO8601DateFormat);
Assert.assertEquals(new java.util.Date(1294552193000L), date);


场景2:
public static class Entity {
	private Date d;

	public Date getD() {
		return d;
	}

	public void setD(Date d) {
		this.d = d;
	}

}

Entity entity = JSON.parseObject("{d:2011-01-09T13:49:53}", Entity.class, Feature.AllowISO8601DateFormat);

Assert.assertEquals(new java.util.Date(1294552193000L), entity.getD());



场景3:
JSONObject object = JSON.parseObject("{d:2011-01-09T13:49:53}", Feature.AllowISO8601DateFormat);
Assert.assertEquals(new java.util.Date(1294552193000L), object.get("d"));

0 请登录后投票
   发表时间:2011-01-09  
wenshao 写道
parser也支持ISO8601的日期格式了,不过不是缺省支持的。如下:

场景1:
java.util.Date date = JSON.parseObject("2011-01-09T13:49:53", java.util.Date.class, Feature.AllowISO8601DateFormat);
Assert.assertEquals(new java.util.Date(1294552193000L), date);


场景2:
public static class Entity {
	private Date d;

	public Date getD() {
		return d;
	}

	public void setD(Date d) {
		this.d = d;
	}

}

Entity entity = JSON.parseObject("{d:2011-01-09T13:49:53}", Entity.class, Feature.AllowISO8601DateFormat);

Assert.assertEquals(new java.util.Date(1294552193000L), entity.getD());



场景3:
JSONObject object = JSON.parseObject("{d:2011-01-09T13:49:53}", Feature.AllowISO8601DateFormat);
Assert.assertEquals(new java.util.Date(1294552193000L), object.get("d"));




"{d:2011-01-09T13:49:53}"
此处d:之后是否应该是字符串呢?JSON规范中尚无原生日期格式,本着“解析从宽,输出从严”的原则,建议输出时输出为字符串,解析则两者皆支持可能更好

不过wenshao真是更新神速,呵呵。
0 请登录后投票
   发表时间:2011-01-09   最后修改:2011-01-09
@厌倦发呆

是的,解析从宽,输出从严,原则和你所说的一样,解析的时候支持的特性如下:
public static final int DEFAULT_PARSER_FEATURE;
static {
	int features = 0;
	features |= Feature.AutoCloseSource.getMask();
	features |= Feature.InternFieldNames.getMask();
	features |= Feature.AllowUnQuotedFieldNames.getMask();
	features |= Feature.AllowSingleQuotes.getMask();
	DEFAULT_PARSER_FEATURE = features;
}



public static final int DEFAULT_GENERATE_FEATURE;
static {
	int features = 0;
	features |= com.alibaba.fastjson.serializer.Feature.QuoteFieldNames.getMask();
	features |= com.alibaba.fastjson.serializer.Feature.WriteMapNullValue.getMask();
	DEFAULT_GENERATE_FEATURE = features;
}
0 请登录后投票
   发表时间:2011-01-09   最后修改:2011-01-09

有效代码代码数量已经到了4713行了,不过测试行覆盖率还保持到100%。以下是sonar的图表:

 

从12月24日时的2000行,增长到了现在的4700行,代码的增长还是挺快的。

 

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics