使用Demjson 坑大了,性能非常慢。
虽然Python对象转成JSON对象还算简单,不过对于我这种不喜欢重复劳动的人来说,还是用别人的库比较安逸。
由于GAE上只能用纯Python的模块,所以C扩展的库就不考虑了,于是大致就只剩这3种了:simplejson、python-json和demjson。
流行度的话,由于simplejson是django的内置模块,自然最高。demjson则是个相对而言比较新的模块。
由于听说python-json性能不佳,而且2005年后就没更新了,所以就懒得测了。
于是就变成simplejson vs demjson了。
先说下版本:
Python:2.5.4
GAE SDK:1.2.2
simplejson:2.0.9
demjson:1.4
再比较下文件:
simplejson是一个包,里面有5个文件。而demjson是单个文件,不过比simplejson的5个文件加起来还大一倍…
不废话了,赶紧测试。
先是编译JSON:
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import memcache
import simplejson
import demjson
from timeit import Timer
class JsonTest(webapp.RequestHandler):
def get(self):
d = {}
for i in xrange(100):
d[i] = u'哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈'
memcache.set('d', d)
setup = '''\
from google.appengine.api import memcache
import simplejson
import demjson
d = memcache.get('d')'''
t1 = Timer('simplejson.dumps(d)', setup).timeit(100)
t2 = Timer('demjson.encode(d)', setup).timeit(100)
self.response.out.write('%s %s' % (t1, t2))
application = webapp.WSGIApplication([('/json/', JsonTest),])
run_wsgi_app(application)
结果:
5.19135889058 1.62516221533
demjson快了3倍多,很强大。
考虑到demjson输出的是unicode,而GAE对外输出时会自动转成string,所以将demjson.encode(d)改成demjson.encode(d).encode("utf8")再次测试,结果:
5.15618079144 1.63971434892
接着看解析JSON:
class JsonTest(webapp.RequestHandler):
def get(self):
d = {}
for i in xrange(100):
d[i] = u'哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈'
memcache.set('d', simplejson.dumps(d)) # 不知道为什么,用demjson.encode(d)的话,simplejson.loads(d)会出错
setup = '''\
from google.appengine.api import memcache
import simplejson
import demjson
d = memcache.get('d')'''
t1 = Timer('simplejson.loads(d)', setup).timeit(50)
t2 = Timer('demjson.decode(d)', setup).timeit(50)
self.response.out.write('%s %s' % (t1, t2))
结果:
1.76071409144 6.35170093493
情况完全反了过来,simplejson快了3倍多…
看来如果要追求性能的话,载入用simplejson,输出用demjson。
写法大概这样:
>>> from demjson import encode as encodeJSON
>>> from simplejson import loads as decodeJSON
>>> d = {'a': '123', 'b': u'哈哈'}
>>> encodeJSON(d)
u'{"a":"123","b":"\u54c8\u54c8"}'
>>> decodeJSON(encodeJSON(d))
{u'a': u'123', u'b': u'\u54c8\u54c8'}
« KAG3文档(不完全汉化第二版)发布了Little Busters年内移植PS2和PSP了 »
1条评论 你不来一发么↓顺序排列倒序排列
-
keakon
今天又测试了一下,发现simplejson在各方面都比demjson好,以前的测试估计有误。
2009-11-17 23:42:20
在兼容性方面,demjson在encode字符串时,如果是非ASCII字符会出错,而simplejson会尝试用UTF-8解码。而输出时,前者是字符串,后者是unicode。如果编码正确的话,表现倒是一样,而且和UTF-8编码的字符串的数据传输量相同;编码设置错误的话,unicode仍能正常显示。
测试数据是来自Google字典,并将字符串改成了unicode,避免demjson解析失败。
simplejson:
结果:# -*- coding: utf-8 -*- from time import clock obj = [u"ero",[[u"erode",u"腐蚀;侵蚀;磨损",u"0",u""],[u"erodent",u"侵蚀的, 腐蚀药",u"1",u""],[u"erogenous",u"唤起情欲的;性感的",u"2",u""],[u"eros",u"【希神】爱神, (eros)性爱",u"3",u""],[u"erose",u"凹凸不平的, 【植】(叶等)有啮蚀状边缘的",u"4",u""],[u"erosion",u"侵蚀;腐蚀",u"5",u""],[u"erosive",u"腐蚀(性)的;浸蚀(性)的",u"6",u""],[u"erotism",u"性爱倾向;性的兴奋",u"7",u""],[u"erotogenic",u"唤起情欲的, 性感带的",u"8",u""],[u"erotomania",u"色情狂",u"9",u""]]] t = clock() import simplejson t2 = clock() json = simplejson.dumps(obj) t3 = clock() obj2 = simplejson.loads(json) t4 = clock() print obj == obj2 print t2 - t print t3 - t2 print t4 - t3
True
demjson:
0.0137319128548
0.000728304854388
0.000640025478098
结果:# -*- coding: utf-8 -*- from time import clock obj = [u"ero",[[u"erode",u"腐蚀;侵蚀;磨损",u"0",u""],[u"erodent",u"侵蚀的, 腐蚀药",u"1",u""],[u"erogenous",u"唤起情欲的;性感的",u"2",u""],[u"eros",u"【希神】爱神, (eros)性爱",u"3",u""],[u"erose",u"凹凸不平的, 【植】(叶等)有啮蚀状边缘的",u"4",u""],[u"erosion",u"侵蚀;腐蚀",u"5",u""],[u"erosive",u"腐蚀(性)的;浸蚀(性)的",u"6",u""],[u"erotism",u"性爱倾向;性的兴奋",u"7",u""],[u"erotogenic",u"唤起情欲的, 性感带的",u"8",u""],[u"erotomania",u"色情狂",u"9",u""]]] t = clock() import demjson t2 = clock() json = demjson.encode(obj) t3 = clock() obj2 = demjson.decode(json) t4 = clock() print obj == obj2 print t2 - t print t3 - t2 print t4 - t3
True
可见无论import模块,还是编码、解码速度,都是simplejson更胜一筹,再加上兼容性更好,因此demjson可以放弃了。
0.017658668909
0.00269810827912
0.00339065439881