blob: f6803575cdb39ddfefa5662541b561616057299d [file] [log] [blame]
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +09001#!/usr/bin/env python
2
3#
4# Licensed to the Apache Software Foundation (ASF) under one
5# or more contributor license agreements. See the NOTICE file
6# distributed with this work for additional information
7# regarding copyright ownership. The ASF licenses this file
8# to you under the Apache License, Version 2.0 (the
9# "License"); you may not use this file except in compliance
10# with the License. You may obtain a copy of the License at
11#
12# http://www.apache.org/licenses/LICENSE-2.0
13#
14# Unless required by applicable law or agreed to in writing,
15# software distributed under the License is distributed on an
16# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17# KIND, either express or implied. See the License for the
18# specific language governing permissions and limitations
19# under the License.
20#
21
22r"""
23PYTHONPATH=./gen-py:../../lib/py/build/lib... ./FastbinaryTest.py
24"""
25
26# TODO(dreiss): Test error cases. Check for memory leaks.
27
28import math
Nobuaki Sukegawaa3b88a02016-01-06 20:44:17 +090029import os
30import sys
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +090031import timeit
32
33from copy import deepcopy
34from pprint import pprint
35
36from thrift.transport import TTransport
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +090037from thrift.protocol.TBinaryProtocol import TBinaryProtocol, TBinaryProtocolAccelerated
38from thrift.protocol.TCompactProtocol import TCompactProtocol, TCompactProtocolAccelerated
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +090039
40from DebugProtoTest import Srv
41from DebugProtoTest.ttypes import Backwards, Bonk, Empty, HolyMoley, OneOfEach, RandomStuff, Wrapper
42
43
44class TDevNullTransport(TTransport.TTransportBase):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090045 def __init__(self):
46 pass
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +090047
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090048 def isOpen(self):
49 return True
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +090050
James E. King, III0ad20bd2017-09-30 15:44:16 -070051
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +090052ooe1 = OneOfEach()
53ooe1.im_true = True
54ooe1.im_false = False
55ooe1.a_bite = 0xd6
56ooe1.integer16 = 27000
57ooe1.integer32 = 1 << 24
58ooe1.integer64 = 6000 * 1000 * 1000
59ooe1.double_precision = math.pi
60ooe1.some_characters = "Debug THIS!"
Nobuaki Sukegawaa3b88a02016-01-06 20:44:17 +090061ooe1.zomg_unicode = u"\xd7\n\a\t"
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +090062
63ooe2 = OneOfEach()
64ooe2.integer16 = 16
65ooe2.integer32 = 32
66ooe2.integer64 = 64
67ooe2.double_precision = (math.sqrt(5) + 1) / 2
68ooe2.some_characters = ":R (me going \"rrrr\")"
Alexandre Detisted0787212024-12-26 02:44:13 +010069ooe2.zomg_unicode = "\xd3\x80\xe2\x85\xae\xce\x9d\x20"\
70 "\xd0\x9d\xce\xbf\xe2\x85\xbf\xd0\xbe"\
71 "\xc9\xa1\xd0\xb3\xd0\xb0\xcf\x81\xe2\x84\x8e"\
72 "\x20\xce\x91\x74\x74\xce\xb1\xe2\x85\xbd\xce\xba"\
73 "\xc7\x83\xe2\x80\xbc"
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +090074
75hm = HolyMoley(**{"big": [], "contain": set(), "bonks": {}})
76hm.big.append(ooe1)
77hm.big.append(ooe2)
78hm.big[0].a_bite = 0x22
79hm.big[1].a_bite = 0x22
80
81hm.contain.add(("and a one", "and a two"))
82hm.contain.add(("then a one, two", "three!", "FOUR!"))
Alexandre Detisted0787212024-12-26 02:44:13 +010083hm.contain.add(("\xd7\n\a\t",))
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +090084hm.contain.add(())
85
86hm.bonks["nothing"] = []
87hm.bonks["something"] = [
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090088 Bonk(**{"type": 1, "message": "Wait."}),
89 Bonk(**{"type": 2, "message": "What?"}),
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +090090]
91hm.bonks["poe"] = [
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090092 Bonk(**{"type": 3, "message": "quoth"}),
93 Bonk(**{"type": 4, "message": "the raven"}),
94 Bonk(**{"type": 5, "message": "nevermore"}),
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +090095]
96
97rs = RandomStuff()
98rs.a = 1
99rs.b = 2
100rs.c = 3
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900101rs.myintlist = list(range(20))
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +0900102rs.maps = {1: Wrapper(**{"foo": Empty()}), 2: Wrapper(**{"foo": Empty()})}
103rs.bigint = 124523452435
104rs.triple = 3.14
105
106# make sure this splits two buffers in a buffered protocol
107rshuge = RandomStuff()
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900108rshuge.myintlist = list(range(10000))
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +0900109
110my_zero = Srv.Janky_result(**{"success": 5})
111
112
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900113class Test(object):
114 def __init__(self, fast, slow):
115 self._fast = fast
116 self._slow = slow
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +0900117
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900118 def _check_write(self, o):
119 trans_fast = TTransport.TMemoryBuffer()
120 trans_slow = TTransport.TMemoryBuffer()
Nobuaki Sukegawa7af189a2016-02-11 16:21:01 +0900121 prot_fast = self._fast(trans_fast, fallback=False)
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900122 prot_slow = self._slow(trans_slow)
123
124 o.write(prot_fast)
125 o.write(prot_slow)
126 ORIG = trans_slow.getvalue()
127 MINE = trans_fast.getvalue()
128 if ORIG != MINE:
129 print("actual : %s\nexpected: %s" % (repr(MINE), repr(ORIG)))
130 raise Exception('write value mismatch')
131
132 def _check_read(self, o):
133 prot = self._slow(TTransport.TMemoryBuffer())
134 o.write(prot)
135
136 slow_version_binary = prot.trans.getvalue()
137
138 prot = self._fast(
Nobuaki Sukegawa7af189a2016-02-11 16:21:01 +0900139 TTransport.TMemoryBuffer(slow_version_binary), fallback=False)
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900140 c = o.__class__()
141 c.read(prot)
142 if c != o:
143 print("actual : ")
144 pprint(repr(c))
145 print("expected: ")
146 pprint(repr(o))
147 raise Exception('read value mismatch')
148
149 prot = self._fast(
150 TTransport.TBufferedTransport(
Nobuaki Sukegawa7af189a2016-02-11 16:21:01 +0900151 TTransport.TMemoryBuffer(slow_version_binary)), fallback=False)
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900152 c = o.__class__()
153 c.read(prot)
154 if c != o:
155 print("actual : ")
156 pprint(repr(c))
157 print("expected: ")
158 pprint(repr(o))
159 raise Exception('read value mismatch')
160
161 def do_test(self):
162 self._check_write(HolyMoley())
163 self._check_read(HolyMoley())
164
165 self._check_write(hm)
166 no_set = deepcopy(hm)
167 no_set.contain = set()
168 self._check_read(no_set)
169 self._check_read(hm)
170
171 self._check_write(rs)
172 self._check_read(rs)
173
174 self._check_write(rshuge)
175 self._check_read(rshuge)
176
177 self._check_write(my_zero)
178 self._check_read(my_zero)
179
180 self._check_read(Backwards(**{"first_tag2": 4, "second_tag1": 2}))
181
182 # One case where the serialized form changes, but only superficially.
183 o = Backwards(**{"first_tag2": 4, "second_tag1": 2})
184 trans_fast = TTransport.TMemoryBuffer()
185 trans_slow = TTransport.TMemoryBuffer()
Nobuaki Sukegawa7af189a2016-02-11 16:21:01 +0900186 prot_fast = self._fast(trans_fast, fallback=False)
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900187 prot_slow = self._slow(trans_slow)
188
189 o.write(prot_fast)
190 o.write(prot_slow)
191 ORIG = trans_slow.getvalue()
192 MINE = trans_fast.getvalue()
193 assert id(ORIG) != id(MINE)
194
Nobuaki Sukegawa7af189a2016-02-11 16:21:01 +0900195 prot = self._fast(TTransport.TMemoryBuffer(), fallback=False)
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900196 o.write(prot)
197 prot = self._slow(
198 TTransport.TMemoryBuffer(prot.trans.getvalue()))
199 c = o.__class__()
200 c.read(prot)
201 if c != o:
202 print("copy: ")
203 pprint(repr(c))
204 print("orig: ")
205 pprint(repr(o))
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +0900206
207
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900208def do_test(fast, slow):
209 Test(fast, slow).do_test()
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +0900210
211
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900212def do_benchmark(protocol, iters=5000, skip_slow=False):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900213 setup = """
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +0900214from __main__ import hm, rs, TDevNullTransport
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900215from thrift.protocol.{0} import {0}{1}
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +0900216trans = TDevNullTransport()
Nobuaki Sukegawa7af189a2016-02-11 16:21:01 +0900217prot = {0}{1}(trans{2})
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +0900218"""
219
Nobuaki Sukegawa7af189a2016-02-11 16:21:01 +0900220 setup_fast = setup.format(protocol, 'Accelerated', ', fallback=False')
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900221 if not skip_slow:
Nobuaki Sukegawa7af189a2016-02-11 16:21:01 +0900222 setup_slow = setup.format(protocol, '', '')
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +0900223
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900224 print("Starting Benchmarks")
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +0900225
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900226 if not skip_slow:
227 print("HolyMoley Standard = %f" %
228 timeit.Timer('hm.write(prot)', setup_slow).timeit(number=iters))
229
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900230 print("HolyMoley Acceler. = %f" %
231 timeit.Timer('hm.write(prot)', setup_fast).timeit(number=iters))
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +0900232
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900233 if not skip_slow:
234 print("FastStruct Standard = %f" %
235 timeit.Timer('rs.write(prot)', setup_slow).timeit(number=iters))
236
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900237 print("FastStruct Acceler. = %f" %
238 timeit.Timer('rs.write(prot)', setup_fast).timeit(number=iters))
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +0900239
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900240
Nobuaki Sukegawa7b894692015-12-23 21:45:06 +0900241if __name__ == '__main__':
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900242 print('Testing TBinaryAccelerated')
243 do_test(TBinaryProtocolAccelerated, TBinaryProtocol)
244 do_benchmark('TBinaryProtocol')
245 print('Testing TCompactAccelerated')
246 do_test(TCompactProtocolAccelerated, TCompactProtocol)
247 do_benchmark('TCompactProtocol')