[pypy-commit] pypy unicode-utf8: make json decoding efficient again
cfbolz
pypy.commits at gmail.com
Tue Jan 22 06:54:46 EST 2019
Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch: unicode-utf8
Changeset: r95695:df16e768b3bb
Date: 2019-01-22 12:49 +0100
http://bitbucket.org/pypy/pypy/changeset/df16e768b3bb/
Log: make json decoding efficient again
diff --git a/pypy/module/_pypyjson/interp_decoder.py b/pypy/module/_pypyjson/interp_decoder.py
--- a/pypy/module/_pypyjson/interp_decoder.py
+++ b/pypy/module/_pypyjson/interp_decoder.py
@@ -248,8 +248,7 @@
self.pos = i+1
return self.space.newdict()
- # XXX this should be improved to use an unwrapped dict
- w_dict = self.space.newdict()
+ d = self._create_empty_dict()
while True:
# parse a key: value
w_name = self.decode_key(i)
@@ -261,13 +260,13 @@
i = self.skip_whitespace(i)
#
w_value = self.decode_any(i)
- self.space.setitem(w_dict, w_name, w_value)
+ d[w_name] = w_value
i = self.skip_whitespace(self.pos)
ch = self.ll_chars[i]
i += 1
if ch == '}':
self.pos = i
- return w_dict
+ return self._create_dict(d)
elif ch == ',':
pass
elif ch == '\0':
@@ -306,6 +305,15 @@
return self.space.newutf8(self.getslice(start, end),
end - start)
+ def _create_dict(self, d):
+ from pypy.objspace.std.dictmultiobject import from_unicode_key_dict
+ return from_unicode_key_dict(self.space, d)
+
+ def _create_empty_dict(self):
+ from pypy.objspace.std.dictmultiobject import create_empty_unicode_key_dict
+ return create_empty_unicode_key_dict(self.space)
+
+
def decode_string_escaped(self, start):
i = self.pos
builder = StringBuilder((i - start) * 2) # just an estimate
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -41,6 +41,16 @@
w_dct.length() <= UNROLL_CUTOFF)
+# for json decoder
+def create_empty_unicode_key_dict(space):
+ return r_dict(unicode_eq, unicode_hash,
+ force_non_null=True)
+
+def from_unicode_key_dict(space, d):
+ strategy = space.fromcache(UnicodeDictStrategy)
+ return W_DictObject(space, strategy, strategy.erase(d))
+
+
class W_DictMultiObject(W_Root):
""" Abstract base class that does not store a strategy. """
__slots__ = ['space', 'dstorage']
@@ -1215,8 +1225,7 @@
return type(w_obj) is space.UnicodeObjectCls
def get_empty_storage(self):
- res = r_dict(unicode_eq, unicode_hash,
- force_non_null=True)
+ res = create_empty_unicode_key_dict(self.space)
return self.erase(res)
def _never_equal_to(self, w_lookup_type):
More information about the pypy-commit
mailing list