encoding: change jsonmap to a list indexed by code point
authorYuya Nishihara <yuya@tcha.org>
Sat, 30 Jan 2016 19:41:34 +0900
changeset 28066 d1cc07123243
parent 28065 6b1fc09c699a
child 28067 69a02b1e947c
encoding: change jsonmap to a list indexed by code point This is slightly faster and convenient to implement a paranoid escaping. $ python -m timeit \ -s 'from mercurial import encoding; data = str(bytearray(xrange(128)))' \ 'encoding.jsonescape(data)' original: 100000 loops, best of 3: 15.1 usec per loop this patch: 100000 loops, best of 3: 13.7 usec per loop
mercurial/encoding.py
--- a/mercurial/encoding.py	Tue Feb 02 15:24:11 2016 +0000
+++ b/mercurial/encoding.py	Sat Jan 30 19:41:34 2016 +0900
@@ -378,7 +378,7 @@
     upper = 1
     other = 0
 
-_jsonmap = {}
+_jsonmap = []
 
 def jsonescape(s):
     '''returns a string suitable for JSON
@@ -408,21 +408,18 @@
     '''
 
     if not _jsonmap:
-        for x in xrange(32):
-            _jsonmap[chr(x)] = "\\u%04x" % x
-        for x in xrange(32, 256):
-            c = chr(x)
-            _jsonmap[c] = c
-        _jsonmap['\x7f'] = '\\u007f'
-        _jsonmap['\t'] = '\\t'
-        _jsonmap['\n'] = '\\n'
-        _jsonmap['\"'] = '\\"'
-        _jsonmap['\\'] = '\\\\'
-        _jsonmap['\b'] = '\\b'
-        _jsonmap['\f'] = '\\f'
-        _jsonmap['\r'] = '\\r'
+        _jsonmap.extend("\\u%04x" % x for x in xrange(32))
+        _jsonmap.extend(chr(x) for x in xrange(32, 256))
+        _jsonmap[0x7f] = '\\u007f'
+        _jsonmap[0x09] = '\\t'
+        _jsonmap[0x0a] = '\\n'
+        _jsonmap[0x22] = '\\"'
+        _jsonmap[0x5c] = '\\\\'
+        _jsonmap[0x08] = '\\b'
+        _jsonmap[0x0c] = '\\f'
+        _jsonmap[0x0d] = '\\r'
 
-    return ''.join(_jsonmap[c] for c in toutf8b(s))
+    return ''.join(_jsonmap[x] for x in bytearray(toutf8b(s)))
 
 _utf8len = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4]