12/25/2012

Ultra szybki JSON, czyli ujson

Kilkanaście godzin temu natknąłem się na moduł ujson, który jest napisany w czystym C i może pochwalić się niebywałą szybkością :) Mimo, iż na stronie modułu są przedstawione testy z trzema innymi popularnymi modułami, sam również postanowiłem to sprawdzić.

Moduł ujson porównałem ze standardowym modułem w pythonie, czyli json.

Dane testowe

Pierwsze dane to obiekt, z którym możemy się najczęściej spotkać przy codziennej pracy z różnego rodzaju api, natomiast do drugich danych wpisałem po prostu to co przyszło mi do głowy ;)
test_data1 = {'status': True, 'msg': 'Message'}
test_data2 = [{'name': 'tomislater', 'age': 24, 'sex': 'male'}, 8461, True, False, 8923, 7162, 1, 6, 7, None, [[True, False], ['!', '?']], 'yeah']

Serializacja do formatu JSON

Do porównania obu bibliotek stworzyłem cztery funkcję. Po dwie do każdej.
def test_json_data1():
    return json.dumps(test_data1)

def test_ujson_data1():
    return ujson.dumps(test_data1)

def test_json_data2():
    return json.dumps(test_data2)

def test_ujson_data2():
    return ujson.dumps(test_data2)
Do mierzenia czasu skorzystałem z modułu timeit ze standardowej biblioteki pythona. Każda funkcja została wywołana milion razy:
json_data1 = timeit.timeit("test_json_data1()", setup="from __main__ import test_json_data1", number=1000000)

ujson_data1 = timeit.timeit("test_ujson_data1()", setup="from __main__ import test_ujson_data1", number=1000000)

json_data2 = timeit.timeit("test_json_data2()", setup="from __main__ import test_json_data2", number=1000000)

ujson_data2 = timeit.timeit("test_ujson_data2()", setup="from __main__ import test_ujson_data2", number=1000000)

Wyniki testów dla serializacji do formatu JSON:

Jak widać, jeżeli chodzi o serializację obiektów, moduł ujson jest o wiele szybszy od standardowego modułu.

Deserializacja z formatu JSON

Sprawdźmy teraz jak oba modły radzą sobie z deserializacją:
test_data1 = '{"status": true, "msg": "Message"}'
test_data2 = '[{"age": 24, "name": "tomislater", "sex": "male"}, 8461, true, false, 8923, 7162, 1, 6, 7, null, [[true, false], ["!", "?"]], "yeah"]'

def test_json_data1():
    return json.loads(test_data1)

def test_ujson_data1():
    return ujson.loads(test_data1)

def test_json_data2():
    return json.loads(test_data2)

def test_ujson_data2():
    return ujson.loads(test_data2)

json_data1 = timeit.timeit("test_json_data1()", setup="from __main__ import test_json_data1", number=1000000)
ujson_data1 = timeit.timeit("test_ujson_data1()", setup="from __main__ import test_ujson_data1", number=1000000)
json_data2 = timeit.timeit("test_json_data2()", setup="from __main__ import test_json_data2", number=1000000)
ujson_data2 = timeit.timeit("test_ujson_data2()", setup="from __main__ import test_ujson_data2", number=1000000)
Wyniki testów dla deserializacji z formatu JSON:

Jak widać twórcy nie kłamią, moduł ten jest naprawdę szybki! Należy jednak pamiętać, że testy to jedno, a praktyka to drugie, dlatego też w najbliższym czasie skorzystam z ów modułu i postaram się podzielić obserwacjami.

Wesołych świąt!