Skip to content

Instantly share code, notes, and snippets.

@smerritt
Last active December 20, 2015 05:59
Show Gist options
  • Save smerritt/6082844 to your computer and use it in GitHub Desktop.
Save smerritt/6082844 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
#
# Benchmark the relative performance of stdlib's json, simplejson, and a
# wrapped simplejson that gives the same API as stdlib's json.
import benchmark
import hashlib
import json as stdjson
import simplejson
from datetime import datetime
# dumped out of MemcacheRing.set(), so it's not just realistic, it's real
# data.
CONTAINER_INFO = {
'bytes': '0',
'cors': {'allow_origin': None,
'expose_headers': None,
'max_age': None},
'meta': {'bert': 'ernie',
'bucky': 'balls',
'holy': 'guacamole',
'pants': 'moderately okayish',
'bit my sister': 'm\xc3\xb8\xc3\xb8se', # møøse
'thing1': 'thing2'},
'object_count': '0',
'read_acl': None,
'status': 204,
'sync_key': None,
'versions': None,
'write_acl': None}
class simple2std(object):
@classmethod
def dumps(cls, obj, *a, **kw):
return simplejson.dumps(obj, *a, **kw)
@classmethod
def loads(cls, s, *a, **kw):
return cls.unicodeify(simplejson.loads(s, *a, **kw))
@classmethod
def unicodeify(cls, data):
if isinstance(data, dict):
keys = data.keys()
# JSON keys are always strings
for oldkey in keys:
if isinstance(oldkey, str):
newkey = oldkey.decode("utf-8")
data[newkey] = cls.unicodeify(data.pop(oldkey))
else:
data[oldkey] = cls.unicodeify(data[oldkey])
return data
elif isinstance(data, list):
return [unicodeify(elem) for elem in data]
elif isinstance(data, str):
return data.decode("utf-8")
else:
return data
# quick test to make sure that this little adapter actually works
adapted = repr(simple2std.loads(simple2std.dumps(CONTAINER_INFO)))
std = repr(stdjson.loads(stdjson.dumps(CONTAINER_INFO)))
if not adapted == std:
print "simplejson\n==========\n%s\n\njson\n====\n%s" % (adapted, std)
exit(1)
class BenchmarkContainerListingGeneration(benchmark.Benchmark):
each = 2000
def setUp(self):
self.container_listing = [
("kitten-%5d.jpg" % i,
datetime.utcfromtimestamp(i).isoformat(),
"application/catphoto",
hashlib.md5(str(i)).hexdigest())
for i in xrange(10000)]
def test_simplejson(self):
simplejson.dumps(self.container_listing)
def test_stdjson(self):
stdjson.dumps(self.container_listing)
class BenchmarkSerializeForMemcache(benchmark.Benchmark):
each = 2000
def test_simplejson(self):
simplejson.dumps(CONTAINER_INFO)
def test_stdjson(self):
stdjson.dumps(CONTAINER_INFO)
def test_simple2std(self):
simple2std.dumps(CONTAINER_INFO)
class BenchmarkDeserializeForMemcache(benchmark.Benchmark):
each = 2000
def setUp(self):
self.serialized_container_info = stdjson.dumps(CONTAINER_INFO)
def test_simplejson(self):
simplejson.loads(self.serialized_container_info)
def test_stdjson(self):
stdjson.loads(self.serialized_container_info)
def test_simple2std(self):
simple2std.loads(self.serialized_container_info)
class BenchmarkInAndOutOfMemcache(benchmark.Benchmark):
"""
Simulate putting things into and pulling things out of memcache.
Takes a wild guess that things get read 10x as often as written.
"""
each = 2000
reads_per_write = 10
def test_simplejson(self):
serialized = simplejson.dumps(CONTAINER_INFO)
for _ in xrange(self.reads_per_write):
simplejson.loads(serialized)
def test_stdjson(self):
serialized = stdjson.dumps(CONTAINER_INFO)
for _ in xrange(self.reads_per_write):
stdjson.loads(serialized)
def test_simple2std(self):
serialized = simple2std.dumps(CONTAINER_INFO)
for _ in xrange(self.reads_per_write):
simple2std.loads(serialized)
if __name__ == "__main__":
benchmark.main(format="markdown", numberFormat="%.6g", each=500)
Benchmark Report
================
BenchmarkContainerListingGeneration
-----------------------------------
name | rank | runs | mean | sd | timesBaseline
-----------|------|------|-----------|------------|--------------
stdjson | 1 | 2000 | 0.0118958 | 0.0015706 | 1.0
simplejson | 2 | 2000 | 0.0240923 | 0.00277233 | 2.02528433383
BenchmarkDeserializeForMemcache
-------------------------------
name | rank | runs | mean | sd | timesBaseline
-----------|------|------|-------------|-------------|--------------
simplejson | 1 | 2000 | 1.57449e-05 | 5.9869e-06 | 1.0
stdjson | 2 | 2000 | 3.1565e-05 | 1.0777e-05 | 2.00476990869
simple2std | 3 | 2000 | 0.000123781 | 3.33413e-05 | 7.86167264798
BenchmarkInAndOutOfMemcache
---------------------------
name | rank | runs | mean | sd | timesBaseline
-----------|------|------|-------------|-------------|--------------
simplejson | 1 | 2000 | 0.00017983 | 7.39404e-05 | 1.0
stdjson | 2 | 2000 | 0.000324748 | 9.72657e-05 | 1.80585949463
simple2std | 3 | 2000 | 0.00130341 | 0.000302468 | 7.24800832071
BenchmarkSerializeForMemcache
-----------------------------
name | rank | runs | mean | sd | timesBaseline
-----------|------|------|-------------|-------------|--------------
stdjson | 1 | 2000 | 1.7156e-05 | 6.03119e-06 | 1.0
simplejson | 2 | 2000 | 2.59206e-05 | 8.56844e-06 | 1.51087794879
simple2std | 3 | 2000 | 2.72608e-05 | 1.04445e-05 | 1.58899350311
Each of the above 22000 runs were run in random, non-consecutive order by
`benchmark` v0.1.5 (http://jspi.es/benchmark) with Python 2.7.2
Darwin-12.4.0-x86_64 on 2013-07-25 19:16:20.
swiftstack@saio:~$ ./jsonbench.py
Benchmark Report
================
BenchmarkContainerListingGeneration
-----------------------------------
name | rank | runs | mean | sd | timesBaseline
-----------|------|------|-----------|------------|--------------
stdjson | 1 | 2000 | 0.0165555 | 0.00334151 | 1.0
simplejson | 2 | 2000 | 0.0233151 | 0.00484242 | 1.40830232922
BenchmarkDeserializeForMemcache
-------------------------------
name | rank | runs | mean | sd | timesBaseline
-----------|------|------|-------------|-------------|--------------
simplejson | 1 | 2000 | 1.8206e-05 | 1.88632e-05 | 1.0
stdjson | 2 | 2000 | 3.43379e-05 | 3.20844e-05 | 1.886074789
simple2std | 3 | 2000 | 8.66287e-05 | 6.16882e-05 | 4.75824859386
BenchmarkInAndOutOfMemcache
---------------------------
name | rank | runs | mean | sd | timesBaseline
-----------|------|------|-------------|-------------|--------------
simplejson | 1 | 2000 | 0.000152598 | 7.54171e-05 | 1.0
stdjson | 2 | 2000 | 0.000276346 | 0.000107572 | 1.81094258024
simple2std | 3 | 2000 | 0.000782394 | 0.000282449 | 5.12716685337
BenchmarkSerializeForMemcache
-----------------------------
name | rank | runs | mean | sd | timesBaseline
-----------|------|------|-------------|-------------|--------------
stdjson | 1 | 2000 | 1.64781e-05 | 1.26021e-05 | 1.0
simplejson | 2 | 2000 | 2.14007e-05 | 2.18155e-05 | 1.2987383164
simple2std | 3 | 2000 | 2.21139e-05 | 1.43221e-05 | 1.3420218769
Each of the above 22000 runs were run in random, non-consecutive order by
`benchmark` v0.1.5 (http://jspi.es/benchmark) with Python 2.7.3
Linux-3.2.0-48-generic-x86_64 on 2013-07-19 21:58:41.
Benchmark Report
================
BenchmarkContainerListingGeneration
-----------------------------------
name | rank | runs | mean | sd | timesBaseline
-----------|------|------|-----------|------------|--------------
simplejson | 1 | 2000 | 0.0288059 | 0.00559889 | 1.0
stdjson | 2 | 2000 | 0.156059 | 0.0304323 | 5.4175906351
BenchmarkDeserializeForMemcache
-------------------------------
name | rank | runs | mean | sd | timesBaseline
-----------|------|------|-------------|-------------|--------------
simplejson | 1 | 2000 | 2.44195e-05 | 2.68104e-05 | 1.0
simple2std | 2 | 2000 | 0.000109777 | 6.14514e-05 | 4.4954600041
stdjson | 3 | 2000 | 0.000307385 | 0.000123539 | 12.587670738
BenchmarkInAndOutOfMemcache
---------------------------
name | rank | runs | mean | sd | timesBaseline
-----------|------|------|-------------|-------------|--------------
simplejson | 1 | 2000 | 0.000250571 | 0.000169417 | 1.0
simple2std | 2 | 2000 | 0.00129531 | 0.00063931 | 5.1694525864
stdjson | 3 | 2000 | 0.00394278 | 0.00177296 | 15.7351911735
BenchmarkSerializeForMemcache
-----------------------------
name | rank | runs | mean | sd | timesBaseline
-----------|------|------|-------------|-------------|--------------
simplejson | 1 | 2000 | 2.67773e-05 | 3.21486e-05 | 1.0
simple2std | 2 | 2000 | 2.77063e-05 | 3.01534e-05 | 1.0346935323
stdjson | 3 | 2000 | 7.65344e-05 | 4.5482e-05 | 2.85818523399
Each of the above 22000 runs were run in random, non-consecutive order by
`benchmark` v0.1.5 (http://jspi.es/benchmark) with Python 2.6.8
Linux-3.2.0-48-generic-x86_64 on 2013-07-19 22:17:04.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment