Skip to content

Commit 4053187

Browse files
crazyengRaj Balaebail
authored andcommitted
speed optimizations in wxf serializer and zlib encoder
1 parent a974d13 commit 4053187

2 files changed

Lines changed: 32 additions & 37 deletions

File tree

wolframclient/serializers/wl.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import absolute_import, print_function, unicode_literals
22

3-
from itertools import chain
3+
from itertools import chain, starmap
44

55
from wolframclient.serializers.base import FormatSerializer
66
from wolframclient.serializers.utils import py_encode_decimal, py_encode_text
@@ -9,16 +9,14 @@
99
from wolframclient.utils.encoding import force_bytes, force_text
1010

1111

12-
def yield_with_separators(iterable, separator=b", ", first=None, last=None):
13-
if first:
14-
yield first
12+
def yield_with_separators(iterable, first, last, separator=b", "):
13+
yield first
1514
for i, arg in enumerate(iterable):
1615
if i:
1716
yield separator
1817
for sub in arg:
1918
yield sub
20-
if last:
21-
yield last
19+
yield last
2220

2321

2422
class WLSerializer(FormatSerializer):
@@ -60,16 +58,14 @@ def serialize_int(self, number):
6058
yield b"%i" % number
6159

6260
def serialize_rule(self, lhs, rhs):
63-
return yield_with_separators((lhs, rhs), separator=b" -> ")
61+
return chain(lhs, (b" -> ",), rhs)
6462

6563
def serialize_rule_delayed(self, lhs, rhs):
66-
return yield_with_separators((lhs, rhs), separator=b" :> ")
64+
return chain(lhs, (b" :> ",), rhs)
6765

6866
def serialize_mapping(self, mapping, **opts):
6967
return yield_with_separators(
70-
(self.serialize_rule(key, value) for key, value in mapping),
71-
first=b"<|",
72-
last=b"|>",
68+
starmap(self.serialize_rule, mapping), first=b"<|", last=b"|>"
7369
)
7470

7571
def serialize_association(self, mapping, **opts):

wolframclient/serializers/wxf.py

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import absolute_import, print_function, unicode_literals
22

3-
from itertools import chain
3+
from itertools import chain, starmap
44

55
from wolframclient.serializers.base import FormatSerializer
66
from wolframclient.serializers.utils import py_encode_decimal, safe_len
@@ -20,7 +20,12 @@
2020
)
2121
from wolframclient.utils import six
2222
from wolframclient.utils.api import zlib
23-
from wolframclient.utils.encoding import force_bytes, force_text
23+
from wolframclient.utils.encoding import concatenate_bytes, force_bytes, force_text
24+
from wolframclient.utils.functional import partition
25+
26+
27+
def serialize_rule(key, value, sep=(WXF_CONSTANTS.Rule,)):
28+
return chain(sep, key, value)
2429

2530

2631
def get_length(iterable, length=None):
@@ -37,6 +42,16 @@ def get_length(iterable, length=None):
3742
return iterable, len(iterable)
3843

3944

45+
def compress(data):
46+
47+
compressor = zlib.compressobj()
48+
49+
for token in map(compressor.compress, map(concatenate_bytes, partition(data, 100))):
50+
yield token
51+
52+
yield compressor.flush()
53+
54+
4055
class WXFSerializer(FormatSerializer):
4156
""" Serialize python objects to WXF. """
4257

@@ -46,25 +61,14 @@ def __init__(self, normalizer=None, compress=False, **opts):
4661

4762
def generate_bytes(self, data):
4863

49-
yield WXF_VERSION
50-
5164
if self.compress:
52-
yield WXF_HEADER_COMPRESS
5365

54-
yield WXF_HEADER_SEPARATOR
66+
return chain(
67+
(WXF_VERSION, WXF_HEADER_COMPRESS, WXF_HEADER_SEPARATOR),
68+
compress(self.encode(data)),
69+
)
5570

56-
if self.compress:
57-
compressor = zlib.compressobj()
58-
if six.PY2:
59-
for payload in self.encode(data):
60-
yield compressor.compress(six.binary_type(payload))
61-
else:
62-
for payload in self.encode(data):
63-
yield compressor.compress(payload)
64-
yield compressor.flush()
65-
else:
66-
for payload in self.encode(data):
67-
yield payload
71+
return chain((WXF_VERSION, WXF_HEADER_SEPARATOR), self.encode(data))
6872

6973
def serialize_symbol(self, name):
7074
yield WXF_CONSTANTS.Symbol
@@ -116,12 +120,9 @@ def serialize_string(self, string):
116120

117121
def serialize_bytes(self, bytes, as_byte_array=not six.PY2):
118122
if as_byte_array:
119-
yield WXF_CONSTANTS.BinaryString
120-
yield varint_bytes(len(bytes))
121-
yield bytes
123+
return (WXF_CONSTANTS.BinaryString, varint_bytes(len(bytes)), bytes)
122124
else:
123-
for token in self.serialize_string(force_text(bytes, encoding="iso8859-1")):
124-
yield token
125+
return self.serialize_string(force_text(bytes, encoding="iso8859-1"))
125126

126127
def serialize_mapping(self, keyvalue, **opts):
127128
# the normalizer is always sending an generator key, value
@@ -130,9 +131,7 @@ def serialize_mapping(self, keyvalue, **opts):
130131

131132
return chain(
132133
(WXF_CONSTANTS.Association, varint_bytes(length)),
133-
chain.from_iterable(
134-
chain((WXF_CONSTANTS.Rule,), key, value) for key, value in iterable
135-
),
134+
chain.from_iterable(starmap(serialize_rule, iterable)),
136135
)
137136

138137
def serialize_numeric_array(self, data, dimensions, wl_type):

0 commit comments

Comments
 (0)