Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Speed test of common serializers on python 2.7.2 (pickle, cPickle, ujson, cjson, simplejson, json, yajl, msgpack)
"""
Dependencies:
pip install tabulate simplejson python-cjson ujson yajl msgpack-python
"""
from timeit import timeit
from tabulate import tabulate
setup = '''d = {
'words': """
Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Mauris adipiscing adipiscing placerat.
Vestibulum augue augue,
pellentesque quis sollicitudin id, adipiscing.
""",
'list': range(100),
'dict': dict((str(i),'a') for i in xrange(100)),
'int': 100,
'float': 100.123456
}'''
setup_pickle = '%s ; import cPickle ; src = cPickle.dumps(d)' % setup
setup_pickle2 = '%s ; import cPickle ; src = cPickle.dumps(d, 2)' % setup
setup_json = '%s ; import json; src = json.dumps(d)' % setup
setup_msgpack = '%s ; src = msgpack.dumps(d)' % setup
tests = [
# (title, setup, enc_test, dec_test)
('pickle (ascii)', 'import pickle; %s' % setup_pickle, 'pickle.dumps(d, 0)', 'pickle.loads(src)'),
('pickle (binary)', 'import pickle; %s' % setup_pickle2, 'pickle.dumps(d, 2)', 'pickle.loads(src)'),
('cPickle (ascii)', 'import cPickle; %s' % setup_pickle, 'cPickle.dumps(d, 0)', 'cPickle.loads(src)'),
('cPickle (binary)', 'import cPickle; %s' % setup_pickle2, 'cPickle.dumps(d, 2)', 'cPickle.loads(src)'),
('json', 'import json; %s' % setup_json, 'json.dumps(d)', 'json.loads(src)'),
('simplejson-3.3.1', 'import simplejson; %s' % setup_json, 'simplejson.dumps(d)', 'simplejson.loads(src)'),
('python-cjson-1.0.5', 'import cjson; %s' % setup_json, 'cjson.encode(d)', 'cjson.decode(src)'),
('ujson-1.33', 'import ujson; %s' % setup_json, 'ujson.dumps(d)', 'ujson.loads(src)'),
('yajl 0.3.5', 'import yajl; %s' % setup_json, 'yajl.dumps(d)', 'yajl.loads(src)'),
('msgpack-python-0.3.0', 'import msgpack; %s' % setup_msgpack, 'msgpack.dumps(d)', 'msgpack.loads(src)'),
]
loops = 15000
enc_table = []
dec_table = []
print "Running tests (%d loops each)" % loops
for title, mod, enc, dec in tests:
print title
print " [Encode]", enc
result = timeit(enc, mod, number=loops)
enc_table.append([title, result])
print " [Decode]", dec
result = timeit(dec, mod, number=loops)
dec_table.append([title, result])
enc_table.sort(key=lambda x: x[1])
enc_table.insert(0, ['Package', 'Seconds'])
dec_table.sort(key=lambda x: x[1])
dec_table.insert(0, ['Package', 'Seconds'])
print "\nEncoding Test (%d loops)" % loops
print tabulate(enc_table, headers="firstrow")
print "\nDecoding Test (%d loops)" % loops
print tabulate(dec_table, headers="firstrow")
"""
OUTPUT:
Running tests (15000 loops each)
pickle (ascii)
[Encode] pickle.dumps(d, 0)
[Decode] pickle.loads(src)
pickle (binary)
[Encode] pickle.dumps(d, 2)
[Decode] pickle.loads(src)
cPickle (ascii)
[Encode] cPickle.dumps(d, 0)
[Decode] cPickle.loads(src)
cPickle (binary)
[Encode] cPickle.dumps(d, 2)
[Decode] cPickle.loads(src)
json
[Encode] json.dumps(d)
[Decode] json.loads(src)
simplejson-3.3.1
[Encode] simplejson.dumps(d)
[Decode] simplejson.loads(src)
python-cjson-1.0.5
[Encode] cjson.encode(d)
[Decode] cjson.decode(src)
ujson-1.33
[Encode] ujson.dumps(d)
[Decode] ujson.loads(src)
yajl 0.3.5
[Encode] yajl.dumps(d)
[Decode] yajl.loads(src)
msgpack-python-0.3.0
[Encode] msgpack.dumps(d)
[Decode] msgpack.loads(src)
Encoding Test (15000 loops)
Package Seconds
-------------------- ---------
ujson-1.33 0.232215
msgpack-python-0.3.0 0.241945
cPickle (binary) 0.305273
yajl 0.3.5 0.634148
python-cjson-1.0.5 0.680604
json 0.780438
simplejson-3.3.1 1.04763
cPickle (ascii) 1.62062
pickle (ascii) 14.0497
pickle (binary) 15.4712
Decoding Test (15000 loops)
Package Seconds
-------------------- ---------
msgpack-python-0.3.0 0.240885
cPickle (binary) 0.393152
ujson-1.33 0.396875
python-cjson-1.0.5 0.694321
yajl 0.3.5 0.748369
simplejson-3.3.1 0.780531
cPickle (ascii) 1.38561
json 1.65921
pickle (binary) 5.20554
pickle (ascii) 17.8767
"""
@dec1985

This comment has been minimized.

Copy link

commented Sep 10, 2014

Thanks.

@LyleScott

This comment has been minimized.

Copy link

commented May 23, 2015

Time to learn some msgpack!

@helinwang

This comment has been minimized.

Copy link

commented May 30, 2017

Thanks! Here is an updated test result on docker image python:2.7. The packages are installed using pip install tabulate simplejson python-cjson ujson yajl msgpack-python (I think the package versions in the log do not reflect real version).

Running tests (15000 loops each)
pickle (ascii)
  [Encode] pickle.dumps(d, 0)
  [Decode] pickle.loads(src)
pickle (binary)
  [Encode] pickle.dumps(d, 2)
  [Decode] pickle.loads(src)
cPickle (ascii)
  [Encode] cPickle.dumps(d, 0)
  [Decode] cPickle.loads(src)
cPickle (binary)
  [Encode] cPickle.dumps(d, 2)
  [Decode] cPickle.loads(src)
json
  [Encode] json.dumps(d)
  [Decode] json.loads(src)
simplejson-3.3.1
  [Encode] simplejson.dumps(d)
  [Decode] simplejson.loads(src)
python-cjson-1.0.5
  [Encode] cjson.encode(d)
  [Decode] cjson.decode(src)
ujson-1.33
  [Encode] ujson.dumps(d)
  [Decode] ujson.loads(src)
yajl 0.3.5
  [Encode] yajl.dumps(d)
  [Decode] yajl.loads(src)
msgpack-python-0.3.0
  [Encode] msgpack.dumps(d)
  [Decode] msgpack.loads(src)

Encoding Test (15000 loops)
Package                 Seconds
--------------------  ---------
cPickle (binary)       0.174544
msgpack-python-0.3.0   0.205447
yajl 0.3.5             0.302159
python-cjson-1.0.5     0.332643
json                   0.399422
ujson-1.33             0.464856
simplejson-3.3.1       0.658939
cPickle (ascii)        0.867376
pickle (ascii)         6.64729
pickle (binary)        6.72656

Decoding Test (15000 loops)
Package                 Seconds
--------------------  ---------
msgpack-python-0.3.0   0.126161
cPickle (binary)       0.223152
python-cjson-1.0.5     0.236071
ujson-1.33             0.244355
simplejson-3.3.1       0.352405
yajl 0.3.5             0.356132
cPickle (ascii)        0.654795
json                   0.923114
pickle (binary)        2.46238
pickle (ascii)         7.38126
@Sebubu

This comment has been minimized.

Copy link

commented Aug 4, 2017

Here is the update code and results for Python3.5.
cPickle and cjson have been removed.

from timeit import timeit
from tabulate import tabulate

setup = '''d = {
    'words': """
        Lorem ipsum dolor sit amet, consectetur adipiscing 
        elit. Mauris adipiscing adipiscing placerat. 
        Vestibulum augue augue, 
        pellentesque quis sollicitudin id, adipiscing.
        """,
    'list': list(range(100)),
    'dict': dict((str(i),'a') for i in range(100)),
    'int': 100,
    'float': 100.123456
}'''

setup_pickle    = '%s ; import pickle ; src = pickle.dumps(d)' % setup
setup_pickle2   = '%s ; import pickle ; src = pickle.dumps(d, 2)' % setup
setup_json      = '%s ; import json; src = json.dumps(d)' % setup
setup_msgpack   = '%s ; src = msgpack.dumps(d)' % setup

tests = [
    # (title, setup, enc_test, dec_test)
    ('pickle (ascii)', 'import pickle; %s' % setup_pickle, 'pickle.dumps(d, 0)', 'pickle.loads(src)'),
    ('pickle (binary)', 'import pickle; %s' % setup_pickle2, 'pickle.dumps(d, 2)', 'pickle.loads(src)'),
    ('json', 'import json; %s' % setup_json, 'json.dumps(d)', 'json.loads(src)'),
    ('simplejson-3.3.1', 'import simplejson; %s' % setup_json, 'simplejson.dumps(d)', 'simplejson.loads(src)'),
    ('ujson-1.33', 'import ujson; %s' % setup_json, 'ujson.dumps(d)', 'ujson.loads(src)'),
    ('yajl 0.3.5', 'import yajl; %s' % setup_json, 'yajl.dumps(d)', 'yajl.loads(src)'),
    ('msgpack-python-0.3.0', 'import msgpack; %s' % setup_msgpack, 'msgpack.dumps(d)', 'msgpack.loads(src)'),
]

loops = 15000
enc_table = []
dec_table = []

print("Running tests (%d loops each)" % loops)

for title, mod, enc, dec in tests:
    print(title)

    print("  [Encode]", enc)
    result = timeit(enc, mod, number=loops)
    enc_table.append([title, result])

    print("  [Decode]", dec)
    result = timeit(dec, mod, number=loops)
    dec_table.append([title, result])

enc_table.sort(key=lambda x: x[1])
enc_table.insert(0, ['Package', 'Seconds'])

dec_table.sort(key=lambda x: x[1])
dec_table.insert(0, ['Package', 'Seconds'])

print("\nEncoding Test (%d loops)" % loops)
print(tabulate(enc_table, headers="firstrow"))

print("\nDecoding Test (%d loops)" % loops)
print(tabulate(dec_table, headers="firstrow"))

Results:

Running tests (15000 loops each)
pickle (ascii)
  [Encode] pickle.dumps(d, 0)
  [Decode] pickle.loads(src)
pickle (binary)
  [Encode] pickle.dumps(d, 2)
  [Decode] pickle.loads(src)
json
  [Encode] json.dumps(d)
  [Decode] json.loads(src)
simplejson-3.3.1
  [Encode] simplejson.dumps(d)
  [Decode] simplejson.loads(src)
ujson-1.33
  [Encode] ujson.dumps(d)
  [Decode] ujson.loads(src)
yajl 0.3.5
  [Encode] yajl.dumps(d)
  [Decode] yajl.loads(src)
msgpack-python-0.3.0
  [Encode] msgpack.dumps(d)
  [Decode] msgpack.loads(src)

Encoding Test (15000 loops)
Package                 Seconds
--------------------  ---------
pickle (binary)        0.143126
ujson-1.33             0.207734
json                   0.469505
yajl 0.3.5             0.470457
msgpack-python-0.3.0   0.471562
pickle (ascii)         0.664861
simplejson-3.3.1       0.678065

Decoding Test (15000 loops)
Package                 Seconds
--------------------  ---------
msgpack-python-0.3.0   0.170831
ujson-1.33             0.251938
pickle (ascii)         0.258618
pickle (binary)        0.292305
yajl 0.3.5             0.463486
json                   0.495874
simplejson-3.3.1       0.63921
@arturoribes

This comment has been minimized.

Copy link

commented Oct 14, 2017

How can it be that encoding with msgpack went from 0.12 seconds in the previous test to 0.47 seconds?

@JellyWX

This comment has been minimized.

Copy link

commented Dec 15, 2017

Here's results for default JSON, Pickle, MsgPack and uMsgPack (Python 3.5):

Encoding Test (30000 loops)
Package                  Seconds
---------------------  ---------
pickle (binary)         0.675608
umsgpack-python-0.4.8   1.37743
msgpack-python-0.4.8    1.38327
json                    2.23619
pickle (ascii)          2.78601

Decoding Test (30000 loops)
Package                  Seconds
---------------------  ---------
msgpack-python-0.4.8    0.842506
umsgpack-python-0.4.8   0.847567
pickle (binary)         1.32874
pickle (ascii)          1.34376
json                    2.95099

Edit: Something was wrong.
UMsgPack is actually much much slower when used from the file.
Here's an updated report:

Encoding Test (30000 loops)
Package                  Seconds
---------------------  ---------
pickle (binary)         0.661877
msgpack-python-0.4.8    1.41231
json                    2.20819
pickle (ascii)          2.7429
umsgpack (WGET) 33.3858

Decoding Test (30000 loops)
Package                  Seconds
---------------------  ---------
msgpack-python-0.4.8    0.815752
pickle (ascii)          1.29843
pickle (binary)         1.31096
json                    2.96718
umsgpack (WGET)  40.3615
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.