Skip to content

Instantly share code, notes, and snippets.

@dchentech
Forked from eamartin/benchmark.py
Last active August 29, 2015 14:20
Show Gist options
  • Save dchentech/02dca2bcc8b0ef1bbfb5 to your computer and use it in GitHub Desktop.
Save dchentech/02dca2bcc8b0ef1bbfb5 to your computer and use it in GitHub Desktop.
# -*-coding:utf-8-*-
'''cjson, jsonlib, simplejson, and yajl also use C code
demjson did not use C code, but was too painfully slow to benchmark
(took about 20 seconds for these tests)
'''
import json
import sys
import time
# Compact between Python literal and JSON format.
false = False
true = True
with open('doc.json') as f:
decoded = f.read()
encoded = json.loads(decoded)
def test_encodes(modules):
encode_times = {}
for json_module in modules:
start = time.clock()
for _ in xrange(10000):
json_module.loads(decoded)
total_time = time.clock() - start
assert json_module.loads(decoded) == encoded, "decoded:%s, encoded:%s" % (decoded, encoded)
encode_times[json_module.__name__] = total_time
return encode_times
def test_decodes(modules):
decode_times = {}
for json_module in modules:
start = time.clock()
for _ in xrange(10000):
json_module.dumps(encoded)
total_time = time.clock() - start
assert json_module.loads(json_module.dumps(encoded)) == encoded, "decoded:%s, encoded:%s" % (decoded, encoded)
decode_times[json_module.__name__] = total_time
return decode_times
def printer(mapping):
''' mapping maps module name to time'''
for k, v in mapping.iteritems():
print '%s: %ss' % (k, v)
import cjson
import jsonlib
import simplejson
import ujson
import yajl
jsonlib.loads = jsonlib.read
jsonlib.dumps = jsonlib.write
cjson.loads = cjson.decode
cjson.dumps = cjson.encode
from bunch import Bunch
python = Bunch({"loads": eval, "dumps": str, "__name__": "Python"})
import jsonpickle
# jsonpickle.load_backend('ujson', 'dumps', 'loads', ValueError)
jsonpickle.load_backend('simplejson', 'dumps', 'loads', ValueError)
jsonpickle.set_preferred_backend('ujson')
jsonpickle.loads = jsonpickle.decode
jsonpickle.dumps = jsonpickle.encode
try:
import cPickle as pickle
except:
import pickle
common_data_type_between_python_and_json = set([str, unicode, int, list, dict, float, bool, type(None)])
class PythonObjectEncoder_json(json.JSONEncoder):
# copied from http://stackoverflow.com/questions/8230315/python-sets-are-not-json-serializable
def default(self, obj):
if isinstance(obj, common_data_type_between_python_and_json):
return json.JSONEncoder.default(self, obj)
return {'__po__': pickle.dumps(obj)}
class PythonObjectEncoder_simplejson(simplejson.JSONEncoder):
def default(self, obj):
if isinstance(obj, common_data_type_between_python_and_json):
return simplejson.JSONEncoder.default(self, obj)
return {'__po__': pickle.dumps(obj)}
def as_python_object(dct):
if '__po__' in dct:
return pickle.loads(str(dct['__po__']))
return dct
json_with_pickle = Bunch({
"loads": lambda value: json.loads(value, object_hook=as_python_object),
"dumps": lambda value: json.dumps(value, cls=PythonObjectEncoder_json),
"__name__": "json_with_pickle"})
simplejson_with_pickle = Bunch({
# "loads": lambda value: simplejson.loads(value, object_hook=as_python_object),
"loads": lambda value: json.loads(value, object_hook=as_python_object), # json is faster
"dumps": lambda value: simplejson.dumps(value, cls=PythonObjectEncoder_simplejson),
"__name__": "simplejson_with_pickle"})
def main():
print 'JSON Benchmark'
try:
import __pypy__
__pypy__ # follow PEP8, make __pypy__ used.
except ImportError:
# we are using CPython
print sys.version.strip()
modules = [cjson, json, jsonlib, simplejson, ujson, yajl, python, jsonpickle, json_with_pickle, simplejson_with_pickle]
else:
# we are using PyPy
print sys.version
modules = [json]
print '-----------------------------'
print 'LOADS'
printer(test_encodes(modules))
print ''
print 'DUMPS'
printer(test_decodes(modules))
if __name__ == '__main__':
main()
{
"web-app": {
"servlet": [
{
"servlet-name": "cofaxCDS",
"servlet-class": "org.cofax.cds.CDSServlet",
"init-param": {
"configGlossary:installationAt": "Philadelphia, PA",
"configGlossary:adminEmail": "[email protected]",
"configGlossary:poweredBy": "Cofax",
"configGlossary:poweredByIcon": "/images/cofax.gif",
"configGlossary:staticPath": "/content/static",
"templateProcessorClass": "org.cofax.WysiwygTemplate",
"templateLoaderClass": "org.cofax.FilesTemplateLoader",
"templatePath": "templates",
"templateOverridePath": "",
"defaultListTemplate": "listTemplate.htm",
"defaultFileTemplate": "articleTemplate.htm",
"useJSP": false,
"jspListTemplate": "listTemplate.jsp",
"jspFileTemplate": "articleTemplate.jsp",
"cachePackageTagsTrack": 200,
"cachePackageTagsStore": 200,
"cachePackageTagsRefresh": 60,
"cacheTemplatesTrack": 100,
"cacheTemplatesStore": 50,
"cacheTemplatesRefresh": 15,
"cachePagesTrack": 200,
"cachePagesStore": 100,
"cachePagesRefresh": 10,
"cachePagesDirtyRead": 10,
"searchEngineListTemplate": "forSearchEnginesList.htm",
"searchEngineFileTemplate": "forSearchEngines.htm",
"dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver",
"dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon",
"dataStoreUser": "sa",
"dataStorePassword": "dataStoreTestQuery",
"dataStoreTestQuery": "SET NOCOUNT ON;select test='test';",
"dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log",
"dataStoreInitConns": 10,
"dataStoreMaxConns": 100,
"dataStoreConnUsageLimit": 100,
"dataStoreLogLevel": "debug",
"maxUrlLength": 500
}
},
{
"servlet-name": "cofaxEmail",
"servlet-class": "org.cofax.cds.EmailServlet",
"init-param": {
"mailHost": "mail1",
"mailHostOverride": "mail2"
}
},
{
"servlet-name": "cofaxAdmin",
"servlet-class": "org.cofax.cds.AdminServlet"
},
{
"servlet-name": "fileServlet",
"servlet-class": "org.cofax.cds.FileServlet"
},
{
"servlet-name": "cofaxTools",
"servlet-class": "org.cofax.cms.CofaxToolsServlet",
"init-param": {
"templatePath": "toolstemplates/",
"log": 1,
"logLocation": "/usr/local/tomcat/logs/CofaxTools.log",
"logMaxSize": "",
"dataLog": 1,
"dataLogLocation": "/usr/local/tomcat/logs/dataLog.log",
"dataLogMaxSize": "",
"removePageCache": "/content/admin/remove?cache=pages&id=",
"removeTemplateCache": "/content/admin/remove?cache=templates&id=",
"fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder",
"lookInContext": 1,
"adminGroupID": 4,
"betaServer": true
}
}
],
"servlet-mapping": {
"cofaxCDS": "/",
"cofaxEmail": "/cofaxutil/aemail/*",
"cofaxAdmin": "/admin/*",
"fileServlet": "/static/*",
"cofaxTools": "/tools/*"
},
"taglib": {
"taglib-uri": "cofax.tld",
"taglib-location": "/WEB-INF/tlds/cofax.tld"
}
}
}
jsonlib==1.6.1
python-cjson==1.0.5
simplejson==2.1.6
ujson==1.4
yajl==0.3.5
jsonpickle==0.9.2
bunch
CPython
JSON Benchmark
2.7.1+ (r271:86832, Apr 11 2011, 18:05:24)
[GCC 4.5.2]
-----------------------------
ENCODING
simplejson: 0.45s
cjson: 0.45s
ujson: 0.46s
jsonlib: 0.65s
json: 1.02s
yajl: 0.7s
DECODING
simplejson: 0.73s
cjson: 0.83s
ujson: 0.41s
jsonlib: 0.48s
json: 0.6s
yajl: 0.59s
PyPy
JSON Benchmark
2.7.1 (b590cf6de419, Apr 30 2011, 02:00:38)
[PyPy 1.5.0-alpha0 with GCC 4.4.3]
-----------------------------
ENCODING
json: 2.839568s
DECODING
json: 5.551157s
JSON Benchmark
2.7.9 (default, Jan 14 2015, 12:59:47)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.56)]
-----------------------------
ENCODING
simplejson: 0.199839s
cjson: 0.338926s
ujson: 0.159075s
jsonlib: 0.295177s
jsonpickle: 3.520997s
Python: 2.39237s
json: 0.575872s
yajl: 0.305689s
json_with_pickle: 0.631806s
simplejson_with_pickle: 0.642256s
DECODING
simplejson: 0.321657s
cjson: 0.265645s
ujson: 0.12081s
jsonlib: 0.183908s
jsonpickle: 4.347567s
Python: 0.315801s
json: 0.262171s
yajl: 0.285239s
json_with_pickle: 0.292358s
simplejson_with_pickle: 0.376733s
### Use list counter
from collections import Counter
encoded = dict(Counter(list(u"""In mathematics, in the field of differential equations, a boundary value problem is a differential equation together with a set of additional constraints, called the boundary conditions. A solution to a boundary value problem is a solution to the differential equation which also satisfies the boundary conditions. Boundary value problems arise in several branches of physics as any physical differential equation will have them. Problems involving the wave equation, such as the determination of normal modes, are often stated as boundary value problems. A large class of important boundary value problems are the Sturm-Liouville problems. The analysis of these problems involves the eigenfunctions of a differential operator. To be useful in applications, a boundary value problem should be well posed. This means that given the input to the problem there exists a unique solution, which depends continuously on the input. Much theoretical work in the field of partial differential equations is devoted to proving that boundary value problems arising from scientific and engineering applications are in fact well-posed. Among the earliest boundary value problems to be studied is the Dirichlet problem, of finding the harmonic functions (solutions to Laplace's equation); the solution was given by the Dirichlet's principle.""")))
decoded = json.dumps(encoded)
JSON Benchmark
2.7.9 (default, Jan 14 2015, 12:59:47)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.56)]
-----------------------------
LOADS
simplejson: 0.098571s
cjson: 0.086123s
ujson: 0.029209s
jsonlib: 0.130403s
jsonpickle: 1.694231s
Python: 0.933695s
json: 0.17748s
yajl: 0.08831s
json_with_pickle: 0.226212s
simplejson_with_pickle: 0.225582s
DUMPS
simplejson: 0.138019s
cjson: 0.071463s
ujson: 0.027976s
jsonlib: 0.043482s
jsonpickle: 2.119171s
Python: 0.089995s
json: 0.108867s
yajl: 0.100177s
json_with_pickle: 0.153227s
simplejson_with_pickle: 0.183107s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment