[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