Faster JSON encoder/decoder

Improve performance of FreeIPA's JSON serializer and deserializer.

* Don't indent and sort keys. Both options trigger a slow path in
  Python's json package. Without indention and sorting, encoding
  mostly happens in optimized C code.
* Replace O(n) type checks with O(1) type lookup and eliminate
  the use of isinstance().
* Check each client capability only once for every conversion.
* Use decoder's obj_hook feature to traverse the object tree once and
  to eliminate calls to isinstance().

Closes: https://fedorahosted.org/freeipa/ticket/6655
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Martin Basti <mbasti@redhat.com>
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
This commit is contained in:
Christian Heimes
2017-02-15 17:27:56 +01:00
committed by Martin Basti
parent 593ea7da9a
commit 8159c2883b
2 changed files with 134 additions and 83 deletions
+3 -5
View File
@@ -25,8 +25,8 @@ Also see the `ipalib.rpc` module.
from xml.sax.saxutils import escape
import os
import json
import traceback
import gssapi
import requests
@@ -483,13 +483,12 @@ class jsonserver(WSGIExecutioner, HTTP_Status):
principal=unicode(principal),
version=unicode(VERSION),
)
response = json_encode_binary(response, version)
dump = json.dumps(response, sort_keys=True, indent=4)
dump = json_encode_binary(response, version)
return dump.encode('utf-8')
def unmarshal(self, data):
try:
d = json.loads(data)
d = json_decode_binary(data)
except ValueError as e:
raise JSONError(error=e)
if not isinstance(d, dict):
@@ -498,7 +497,6 @@ class jsonserver(WSGIExecutioner, HTTP_Status):
raise JSONError(error=_('Request is missing "method"'))
if 'params' not in d:
raise JSONError(error=_('Request is missing "params"'))
d = json_decode_binary(d)
method = d['method']
params = d['params']
_id = d.get('id')