Skip to content

Commit 69ba3c9

Browse files
committed
fallback: use __pypy__.builders.StringBuilder when available
This increases performance *a lot* on PyPy. Signed-off-by: Bas Westerbaan <bas@westerbaan.name>
1 parent 2627b6a commit 69ba3c9

File tree

1 file changed

+36
-10
lines changed

1 file changed

+36
-10
lines changed

msgpack/fallback.py

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,28 @@
44
import array
55
import struct
66

7-
try:
8-
import cStringIO as StringIO
9-
except ImportError:
10-
import StringIO
7+
if hasattr(sys, 'pypy_version_info'):
8+
# cStringIO is slow on PyPy, StringIO is faster. However: PyPy's own
9+
# StringBuilder is fastest.
10+
from __pypy__.builders import StringBuilder
11+
USING_STRINGBUILDER = True
12+
class StringIO(object):
13+
def __init__(self, s=''):
14+
if s:
15+
self.builder = StringBuilder(len(s))
16+
self.builder.append(s)
17+
else:
18+
self.builder = StringBuilder()
19+
def write(self, s):
20+
self.builder.append(s)
21+
def getvalue(self):
22+
return self.builder.build()
23+
else:
24+
USING_STRINGBUILDER = False
25+
try:
26+
from cStringIO import StringIO
27+
except ImportError:
28+
from StringIO import StringIO
1129

1230
from msgpack.exceptions import (
1331
BufferFull,
@@ -362,7 +380,7 @@ def __init__(self, default=None, encoding='utf-8', unicode_errors='strict',
362380
self.autoreset = autoreset
363381
self.encoding = encoding
364382
self.unicode_errors = unicode_errors
365-
self.buffer = StringIO.StringIO()
383+
self.buffer = StringIO()
366384
if default is not None:
367385
if not callable(default):
368386
raise TypeError("default must be callable")
@@ -429,25 +447,33 @@ def pack(self, obj):
429447
self._pack(obj)
430448
ret = self.buffer.getvalue()
431449
if self.autoreset:
432-
self.buffer = StringIO.StringIO()
450+
self.buffer = StringIO()
451+
elif USING_STRINGBUILDER:
452+
self.buffer = StringIO(ret)
433453
return ret
434454
def pack_map_pairs(self, pairs):
435455
self._fb_pack_map_pairs(len(pairs), pairs)
436456
ret = self.buffer.getvalue()
437457
if self.autoreset:
438-
self.buffer = StringIO.StringIO()
458+
self.buffer = StringIO()
459+
elif USING_STRINGBUILDER:
460+
self.buffer = StringIO(ret)
439461
return ret
440462
def pack_array_header(self, n):
441463
self._fb_pack_array_header(n)
442464
ret = self.buffer.getvalue()
443465
if self.autoreset:
444-
self.buffer = StringIO.StringIO()
466+
self.buffer = StringIO()
467+
elif USING_STRINGBUILDER:
468+
self.buffer = StringIO(ret)
445469
return ret
446470
def pack_map_header(self, n):
447471
self._fb_pack_map_header(n)
448472
ret = self.buffer.getvalue()
449473
if self.autoreset:
450-
self.buffer = StringIO.StringIO()
474+
self.buffer = StringIO()
475+
elif USING_STRINGBUILDER:
476+
self.buffer = StringIO(ret)
451477
return ret
452478
def _fb_pack_array_header(self, n):
453479
if n <= 0x0f:
@@ -473,4 +499,4 @@ def _fb_pack_map_pairs(self, n, pairs, nest_limit=DEFAULT_RECURSE_LIMIT):
473499
def bytes(self):
474500
return self.buffer.getvalue()
475501
def reset(self):
476-
self.buffer = StringIO.StringIO()
502+
self.buffer = StringIO()

0 commit comments

Comments
 (0)