Skip to content

Commit a2b9afa

Browse files
committed
pack performance
1 parent 8d8e727 commit a2b9afa

1 file changed

Lines changed: 118 additions & 119 deletions

File tree

src/msgpack_stream/_msgpack.py

Lines changed: 118 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -38,110 +38,107 @@
3838

3939

4040
def pack_stream(stream, obj):
41-
_ps = pack_stream
42-
_b = _B
43-
_write = stream.write
4441
_type = type(obj)
4542
if _type is int:
4643
i = obj
4744
if 0 <= i <= 0x7F: # positive fixint
48-
_write(_b[i])
45+
stream.write(_B[i])
4946
elif -32 <= i < 0: # negative fixint
50-
_write(_b[i & 0xFF])
47+
stream.write(_B[i & 0xFF])
5148
elif i < 0: # wider negative
52-
ai = -i
53-
if ai <= 0x80:
54-
_write(b"\xd0")
49+
u_i = -i
50+
if u_i <= 0x80:
51+
stream.write(b"\xd0")
5552
s8_b_pack(stream, i)
56-
elif ai <= 0x80_00:
57-
_write(b"\xd1")
53+
elif u_i <= 0x80_00:
54+
stream.write(b"\xd1")
5855
s16_b_pack(stream, i)
59-
elif ai <= 0x80_00_00_00:
60-
_write(b"\xd2")
56+
elif u_i <= 0x80_00_00_00:
57+
stream.write(b"\xd2")
6158
s32_b_pack(stream, i)
62-
elif ai <= 0x80_00_00_00_00_00_00_00:
63-
_write(b"\xd3")
59+
elif u_i <= 0x80_00_00_00_00_00_00_00:
60+
stream.write(b"\xd3")
6461
s64_b_pack(stream, i)
6562
else:
6663
raise ValueError("int too large")
6764
elif i <= 0xFF:
68-
_write(b"\xcc")
65+
stream.write(b"\xcc")
6966
u8_b_pack(stream, i)
7067
elif i <= 0xFF_FF:
71-
_write(b"\xcd")
68+
stream.write(b"\xcd")
7269
u16_b_pack(stream, i)
7370
elif i <= 0xFF_FF_FF_FF:
74-
_write(b"\xce")
71+
stream.write(b"\xce")
7572
u32_b_pack(stream, i)
7673
elif i <= 0xFF_FF_FF_FF_FF_FF_FF_FF:
77-
_write(b"\xcf")
74+
stream.write(b"\xcf")
7875
u64_b_pack(stream, i)
7976
else:
8077
raise ValueError("uint too large")
8178
elif _type is float:
82-
_write(b"\xcb")
79+
stream.write(b"\xcb")
8380
f64_b_pack(stream, obj)
8481
elif _type is dict:
85-
map_length = len(obj)
86-
if map_length <= 0x0F:
87-
_write(_b[0x80 | map_length])
88-
elif map_length <= 0xFF_FF:
89-
_write(b"\xde")
90-
u16_b_pack(stream, map_length)
91-
elif map_length <= 0xFF_FF_FF_FF:
92-
_write(b"\xdf")
93-
u32_b_pack(stream, map_length)
82+
ml = len(obj)
83+
if ml <= 0x0F:
84+
stream.write(_B[0x80 | ml])
85+
elif ml <= 0xFF_FF:
86+
stream.write(b"\xde")
87+
u16_b_pack(stream, ml)
88+
elif ml <= 0xFF_FF_FF_FF:
89+
stream.write(b"\xdf")
90+
u32_b_pack(stream, ml)
9491
else:
9592
raise ValueError("map too large", obj)
9693
for k, v in obj.items():
97-
_ps(stream, k)
98-
_ps(stream, v)
94+
pack_stream(stream, k)
95+
pack_stream(stream, v)
9996
elif _type is list:
100-
array_length = len(obj)
101-
if array_length <= 0x0F:
102-
_write(_b[0x90 | array_length])
103-
elif array_length <= 0xFF_FF:
104-
_write(b"\xdc")
105-
u16_b_pack(stream, array_length)
106-
elif array_length <= 0xFF_FF_FF_FF:
107-
_write(b"\xdd")
108-
u32_b_pack(stream, array_length)
97+
al = len(obj)
98+
if al <= 0x0F:
99+
stream.write(_B[0x90 | al])
100+
elif al <= 0xFF_FF:
101+
stream.write(b"\xdc")
102+
u16_b_pack(stream, al)
103+
elif al <= 0xFF_FF_FF_FF:
104+
stream.write(b"\xdd")
105+
u32_b_pack(stream, al)
109106
else:
110107
raise ValueError("array too large", obj)
111108
for v in obj:
112-
_ps(stream, v)
109+
pack_stream(stream, v)
113110
elif _type is str:
114111
s = obj.encode("utf-8")
115112
sl = len(s)
116113
if sl <= 0x1F:
117-
_write(_b[0xA0 | sl])
114+
stream.write(_B[0xA0 | sl])
118115
elif sl <= 0xFF:
119-
_write(b"\xd9")
116+
stream.write(b"\xd9")
120117
elif sl <= 0xFF_FF:
121-
_write(b"\xda")
118+
stream.write(b"\xda")
122119
elif sl <= 0xFF_FF_FF_FF:
123-
_write(b"\xdb")
120+
stream.write(b"\xdb")
124121
else:
125122
raise ValueError("str too large", obj)
126-
_write(s)
123+
stream.write(s)
127124
elif obj is None:
128-
_write(b"\xc0")
125+
stream.write(b"\xc0")
129126
elif _type is bool:
130-
_write(b"\xc3" if obj else b"\xc2")
127+
stream.write(b"\xc3" if obj else b"\xc2")
131128
elif _type is bytes:
132-
bin_length = len(obj)
133-
if bin_length <= 0xFF:
134-
_write(b"\xc4")
135-
u8_b_pack(stream, bin_length)
136-
elif bin_length <= 0xFF_FF:
137-
_write(b"\xc5")
138-
u16_b_pack(stream, bin_length)
139-
elif bin_length <= 0xFF_FF_FF_FF:
140-
_write(b"\xc6")
141-
u32_b_pack(stream, bin_length)
129+
bl = len(obj)
130+
if bl <= 0xFF:
131+
stream.write(b"\xc4")
132+
u8_b_pack(stream, bl)
133+
elif bl <= 0xFF_FF:
134+
stream.write(b"\xc5")
135+
u16_b_pack(stream, bl)
136+
elif bl <= 0xFF_FF_FF_FF:
137+
stream.write(b"\xc6")
138+
u32_b_pack(stream, bl)
142139
else:
143140
raise ValueError("bin too large", obj)
144-
_write(obj)
141+
stream.write(obj)
145142
else:
146143
raise TypeError("type not supported:", obj, type(obj))
147144

@@ -150,76 +147,78 @@ def unpack_stream(stream):
150147
b = stream.read(1)
151148
first_byte = b[0]
152149
if first_byte <= 0x7F: # positive fixint
153-
return first_byte
154-
if first_byte >= 0xE0: # negative fixint
155-
return first_byte - 0x100
156-
if first_byte <= 0x8F: # fixmap
157-
mlen = first_byte & 0x0F
158-
return {unpack_stream(stream): unpack_stream(stream) for _ in range(mlen)}
159-
if first_byte <= 0x9F: # fixarray
160-
alen = first_byte & 0x0F
161-
return [unpack_stream(stream) for _ in range(alen)]
162-
if first_byte <= 0xBF: # fixstr
163-
slen = first_byte & 0x1F
164-
return stream.read(slen).decode("utf-8")
165-
if first_byte == 0xC0:
166-
return None
167-
if first_byte == 0xC2:
168-
return False
169-
if first_byte == 0xC3:
170-
return True
171-
if first_byte == 0xC4:
150+
obj = first_byte
151+
elif first_byte >= 0xE0: # negative fixint
152+
obj = first_byte - 0x100
153+
elif first_byte <= 0x8F: # fixmap
154+
ml = first_byte & 0x0F
155+
obj = {unpack_stream(stream): unpack_stream(stream) for _ in range(ml)}
156+
elif first_byte <= 0x9F: # fixarray
157+
al = first_byte & 0x0F
158+
obj = [unpack_stream(stream) for _ in range(al)]
159+
elif first_byte <= 0xBF: # fixstr
160+
sl = first_byte & 0x1F
161+
obj = stream.read(sl).decode("utf-8")
162+
elif first_byte == 0xC0:
163+
obj = None
164+
elif first_byte == 0xC2:
165+
obj = False
166+
elif first_byte == 0xC3:
167+
obj = True
168+
elif first_byte == 0xC4:
172169
bl = u8_b_unpack(stream)
173-
return stream.read(bl)
174-
if first_byte == 0xC5:
170+
obj = stream.read(bl)
171+
elif first_byte == 0xC5:
175172
bl = u16_b_unpack(stream)
176-
return stream.read(bl)
177-
if first_byte == 0xC6:
173+
obj = stream.read(bl)
174+
elif first_byte == 0xC6:
178175
bl = u32_b_unpack(stream)
179-
return stream.read(bl)
180-
if 0xC7 <= first_byte <= 0xC9:
176+
obj = stream.read(bl)
177+
elif 0xC7 <= first_byte <= 0xC9:
181178
raise NotImplementedError
182-
if first_byte == 0xCA:
183-
return f32_b_unpack(stream)
184-
if first_byte == 0xCB:
185-
return f64_b_unpack(stream)
186-
if first_byte == 0xCC:
187-
return u8_b_unpack(stream)
188-
if first_byte == 0xCD:
189-
return u16_b_unpack(stream)
190-
if first_byte == 0xCE:
191-
return u32_b_unpack(stream)
192-
if first_byte == 0xCF:
193-
return u64_b_unpack(stream)
194-
if first_byte == 0xD0:
195-
return s8_b_unpack(stream)
196-
if first_byte == 0xD1:
197-
return s16_b_unpack(stream)
198-
if first_byte == 0xD2:
199-
return s32_b_unpack(stream)
200-
if first_byte == 0xD3:
201-
return s64_b_unpack(stream)
202-
if 0xD4 <= first_byte <= 0xD8:
179+
elif first_byte == 0xCA:
180+
obj = f32_b_unpack(stream)
181+
elif first_byte == 0xCB:
182+
obj = f64_b_unpack(stream)
183+
elif first_byte == 0xCC:
184+
obj = u8_b_unpack(stream)
185+
elif first_byte == 0xCD:
186+
obj = u16_b_unpack(stream)
187+
elif first_byte == 0xCE:
188+
obj = u32_b_unpack(stream)
189+
elif first_byte == 0xCF:
190+
obj = u64_b_unpack(stream)
191+
elif first_byte == 0xD0:
192+
obj = s8_b_unpack(stream)
193+
elif first_byte == 0xD1:
194+
obj = s16_b_unpack(stream)
195+
elif first_byte == 0xD2:
196+
obj = s32_b_unpack(stream)
197+
elif first_byte == 0xD3:
198+
obj = s64_b_unpack(stream)
199+
elif 0xD4 <= first_byte <= 0xD8:
203200
raise NotImplementedError
204-
if first_byte == 0xD9:
201+
elif first_byte == 0xD9:
205202
sl = u8_b_unpack(stream)
206-
return stream.read(sl).decode("utf-8")
207-
if first_byte == 0xDA:
203+
obj = stream.read(sl).decode("utf-8")
204+
elif first_byte == 0xDA:
208205
sl = u16_b_unpack(stream)
209-
return stream.read(sl).decode("utf-8")
210-
if first_byte == 0xDB:
206+
obj = stream.read(sl).decode("utf-8")
207+
elif first_byte == 0xDB:
211208
sl = u32_b_unpack(stream)
212-
return stream.read(sl).decode("utf-8")
213-
if first_byte == 0xDC:
209+
obj = stream.read(sl).decode("utf-8")
210+
elif first_byte == 0xDC:
214211
al = u16_b_unpack(stream)
215-
return [unpack_stream(stream) for _ in range(al)]
216-
if first_byte == 0xDD:
212+
obj = [unpack_stream(stream) for _ in range(al)]
213+
elif first_byte == 0xDD:
217214
al = u32_b_unpack(stream)
218-
return [unpack_stream(stream) for _ in range(al)]
219-
if first_byte == 0xDE:
215+
obj = [unpack_stream(stream) for _ in range(al)]
216+
elif first_byte == 0xDE:
220217
ml = u16_b_unpack(stream)
221-
return {unpack_stream(stream): unpack_stream(stream) for _ in range(ml)}
222-
if first_byte == 0xDF:
218+
obj = {unpack_stream(stream): unpack_stream(stream) for _ in range(ml)}
219+
elif first_byte == 0xDF:
223220
ml = u32_b_unpack(stream)
224-
return {unpack_stream(stream): unpack_stream(stream) for _ in range(ml)}
225-
raise ValueError("invalid first byte", first_byte, hex(first_byte))
221+
obj = {unpack_stream(stream): unpack_stream(stream) for _ in range(ml)}
222+
else:
223+
raise ValueError("invalid first byte", first_byte, hex(first_byte))
224+
return obj

0 commit comments

Comments
 (0)