diff options
author | INADA Naoki <songofacandy@gmail.com> | 2013-02-03 08:11:34 -0800 |
---|---|---|
committer | INADA Naoki <songofacandy@gmail.com> | 2013-02-03 08:11:34 -0800 |
commit | 2330e6c7d92455c84fef4b7f9ac44b2a8b430def (patch) | |
tree | c4a2a3ba74d4f5788b8dd507553f23b8d2ff2519 | |
parent | 266eaf813d4e958dce5a2a8c4a84babf331369f0 (diff) | |
parent | 1951b197b547c3f12b755790717d799272fbeb34 (diff) | |
download | msgpack-python-2330e6c7d92455c84fef4b7f9ac44b2a8b430def.tar.gz |
Merge pull request #45 from msgpack/purepython
fallback enhancements.
-rw-r--r-- | benchmark/benchmark.py | 32 | ||||
-rw-r--r-- | msgpack/fallback.py | 25 | ||||
-rw-r--r-- | setup.py | 32 | ||||
-rw-r--r-- | test/test_pack.py | 2 |
4 files changed, 68 insertions, 23 deletions
diff --git a/benchmark/benchmark.py b/benchmark/benchmark.py new file mode 100644 index 0000000..1439289 --- /dev/null +++ b/benchmark/benchmark.py @@ -0,0 +1,32 @@ +from msgpack import fallback +try: + from msgpack import _unpacker, _packer + has_ext = True +except ImportError: + has_ext = False +import timeit + + +def profile(name, func): + times = timeit.repeat(func, number=1000, repeat=4) + times = ', '.join(["%8f" % t for t in times]) + print("%-30s %40s" % (name, times)) + + +def simple(name, data): + if has_ext: + profile("packing %s (ext)" % name, lambda: _packer.packb(data)) + profile('packing %s (fallback)' % name, lambda: fallback.packb(data)) + + data = fallback.packb(data) + if has_ext: + profile('unpacking %s (ext)' % name, lambda: _unpacker.unpackb(data)) + profile('unpacking %s (fallback)' % name, lambda: fallback.unpackb(data)) + +def main(): + simple("integers", [7]*10000) + simple("bytes", [b'x'*n for n in range(100)]*10) + simple("lists", [[]]*10000) + simple("dicts", [{}]*10000) + +main() diff --git a/msgpack/fallback.py b/msgpack/fallback.py index ac6dbf9..c10c6ac 100644 --- a/msgpack/fallback.py +++ b/msgpack/fallback.py @@ -360,16 +360,19 @@ class Unpacker(object): self._fb_unpack(EX_SKIP, write_bytes) self._fb_unpack(EX_SKIP, write_bytes) return - ret = [] - for i in xrange(n): - ret.append((self._fb_unpack(EX_CONSTRUCT, write_bytes), - self._fb_unpack(EX_CONSTRUCT, write_bytes))) if self.object_pairs_hook is not None: - ret = self.object_pairs_hook(ret) + ret = self.object_pairs_hook( + (self._fb_unpack(EX_CONSTRUCT, write_bytes), + self._fb_unpack(EX_CONSTRUCT, write_bytes)) + for _ in xrange(n) + ) else: - ret = dict(ret) - if self.object_hook is not None: - ret = self.object_hook(ret) + ret = {} + for _ in xrange(n): + key = self._fb_unpack(EX_CONSTRUCT, write_bytes) + ret[key] = self._fb_unpack(EX_CONSTRUCT, write_bytes) + if self.object_hook is not None: + ret = self.object_hook(ret) return ret if execute == EX_SKIP: return @@ -421,7 +424,7 @@ class Packer(object): raise TypeError("default must be callable") self._default = default - def _pack(self, obj, nest_limit=DEFAULT_RECURSE_LIMIT): + def _pack(self, obj, nest_limit=DEFAULT_RECURSE_LIMIT, isinstance=isinstance): if nest_limit < 0: raise PackValueError("recursion limit exceeded") if obj is None: @@ -454,6 +457,10 @@ class Packer(object): raise PackValueError("Integer value out of range") if isinstance(obj, (Unicode, bytes)): if isinstance(obj, Unicode): + if self.encoding is None: + raise TypeError( + "Can't encode unicode string: " + "no encoding is specified") obj = obj.encode(self.encoding, self.unicode_errors) n = len(obj) if n <= 0x1f: @@ -46,7 +46,12 @@ class BuildExt(build_ext): print("Install Cython >= 0.16 or install msgpack from PyPI.") print("Falling back to pure Python implementation.") return - return build_ext.build_extension(self, ext) + try: + return build_ext.build_extension(self, ext) + except Exception as e: + print("WARNING: Failed to compile extensiom modules.") + print("msgpack uses fallback pure python implementation.") + print(e) exec(open('msgpack/_version.py').read()) @@ -75,18 +80,19 @@ else: macros = [('__LITTLE_ENDIAN__', '1')] ext_modules = [] -ext_modules.append(Extension('msgpack._packer', - sources=['msgpack/_packer.cpp'], - libraries=libraries, - include_dirs=['.'], - define_macros=macros, - )) -ext_modules.append(Extension('msgpack._unpacker', - sources=['msgpack/_unpacker.cpp'], - libraries=libraries, - include_dirs=['.'], - define_macros=macros, - )) +if not hasattr(sys, 'pypy_version_info'): + ext_modules.append(Extension('msgpack._packer', + sources=['msgpack/_packer.cpp'], + libraries=libraries, + include_dirs=['.'], + define_macros=macros, + )) + ext_modules.append(Extension('msgpack._unpacker', + sources=['msgpack/_unpacker.cpp'], + libraries=libraries, + include_dirs=['.'], + define_macros=macros, + )) del libraries, macros diff --git a/test/test_pack.py b/test/test_pack.py index 8f4117c..3225f41 100644 --- a/test/test_pack.py +++ b/test/test_pack.py @@ -151,7 +151,7 @@ def test_odict(): od = odict(seq) assert unpackb(packb(od), use_list=1) == dict(seq) def pair_hook(seq): - return seq + return list(seq) assert unpackb(packb(od), object_pairs_hook=pair_hook, use_list=1) == seq |