| 30 |
ashish |
1 |
#!/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 |
|
|
|
22 |
r"""
|
|
|
23 |
thrift --gen py DebugProtoTest.thrift
|
|
|
24 |
./FastbinaryTest.py
|
|
|
25 |
"""
|
|
|
26 |
|
|
|
27 |
# TODO(dreiss): Test error cases. Check for memory leaks.
|
|
|
28 |
|
|
|
29 |
import sys
|
|
|
30 |
sys.path.append('./gen-py')
|
|
|
31 |
|
|
|
32 |
import math
|
|
|
33 |
from DebugProtoTest import Srv
|
|
|
34 |
from DebugProtoTest.ttypes import *
|
|
|
35 |
from thrift.transport import TTransport
|
|
|
36 |
from thrift.protocol import TBinaryProtocol
|
|
|
37 |
|
|
|
38 |
import timeit
|
|
|
39 |
from cStringIO import StringIO
|
|
|
40 |
from copy import deepcopy
|
|
|
41 |
from pprint import pprint
|
|
|
42 |
|
|
|
43 |
class TDevNullTransport(TTransport.TTransportBase):
|
|
|
44 |
def __init__(self):
|
|
|
45 |
pass
|
|
|
46 |
def isOpen(self):
|
|
|
47 |
return True
|
|
|
48 |
|
|
|
49 |
ooe1 = OneOfEach()
|
|
|
50 |
ooe1.im_true = True;
|
|
|
51 |
ooe1.im_false = False;
|
|
|
52 |
ooe1.a_bite = 0xd6;
|
|
|
53 |
ooe1.integer16 = 27000;
|
|
|
54 |
ooe1.integer32 = 1<<24;
|
|
|
55 |
ooe1.integer64 = 6000 * 1000 * 1000;
|
|
|
56 |
ooe1.double_precision = math.pi;
|
|
|
57 |
ooe1.some_characters = "Debug THIS!";
|
|
|
58 |
ooe1.zomg_unicode = "\xd7\n\a\t";
|
|
|
59 |
|
|
|
60 |
ooe2 = OneOfEach();
|
|
|
61 |
ooe2.integer16 = 16;
|
|
|
62 |
ooe2.integer32 = 32;
|
|
|
63 |
ooe2.integer64 = 64;
|
|
|
64 |
ooe2.double_precision = (math.sqrt(5)+1)/2;
|
|
|
65 |
ooe2.some_characters = ":R (me going \"rrrr\")";
|
|
|
66 |
ooe2.zomg_unicode = "\xd3\x80\xe2\x85\xae\xce\x9d\x20"\
|
|
|
67 |
"\xd0\x9d\xce\xbf\xe2\x85\xbf\xd0\xbe"\
|
|
|
68 |
"\xc9\xa1\xd0\xb3\xd0\xb0\xcf\x81\xe2\x84\x8e"\
|
|
|
69 |
"\x20\xce\x91\x74\x74\xce\xb1\xe2\x85\xbd\xce\xba"\
|
|
|
70 |
"\xc7\x83\xe2\x80\xbc";
|
|
|
71 |
|
|
|
72 |
hm = HolyMoley({"big":[], "contain":set(), "bonks":{}})
|
|
|
73 |
hm.big.append(ooe1)
|
|
|
74 |
hm.big.append(ooe2)
|
|
|
75 |
hm.big[0].a_bite = 0x22;
|
|
|
76 |
hm.big[1].a_bite = 0x22;
|
|
|
77 |
|
|
|
78 |
hm.contain.add(("and a one", "and a two"))
|
|
|
79 |
hm.contain.add(("then a one, two", "three!", "FOUR!"))
|
|
|
80 |
hm.contain.add(())
|
|
|
81 |
|
|
|
82 |
hm.bonks["nothing"] = [];
|
|
|
83 |
hm.bonks["something"] = [
|
|
|
84 |
Bonk({"type":1, "message":"Wait."}),
|
|
|
85 |
Bonk({"type":2, "message":"What?"}),
|
|
|
86 |
]
|
|
|
87 |
hm.bonks["poe"] = [
|
|
|
88 |
Bonk({"type":3, "message":"quoth"}),
|
|
|
89 |
Bonk({"type":4, "message":"the raven"}),
|
|
|
90 |
Bonk({"type":5, "message":"nevermore"}),
|
|
|
91 |
]
|
|
|
92 |
|
|
|
93 |
rs = RandomStuff()
|
|
|
94 |
rs.a = 1
|
|
|
95 |
rs.b = 2
|
|
|
96 |
rs.c = 3
|
|
|
97 |
rs.myintlist = range(20)
|
|
|
98 |
rs.maps = {1:Wrapper({"foo":Empty()}),2:Wrapper({"foo":Empty()})}
|
|
|
99 |
rs.bigint = 124523452435L
|
|
|
100 |
rs.triple = 3.14
|
|
|
101 |
|
|
|
102 |
# make sure this splits two buffers in a buffered protocol
|
|
|
103 |
rshuge = RandomStuff()
|
|
|
104 |
rshuge.myintlist=range(10000)
|
|
|
105 |
|
|
|
106 |
my_zero = Srv.Janky_result({"arg":5})
|
|
|
107 |
|
|
|
108 |
def checkWrite(o):
|
|
|
109 |
trans_fast = TTransport.TMemoryBuffer()
|
|
|
110 |
trans_slow = TTransport.TMemoryBuffer()
|
|
|
111 |
prot_fast = TBinaryProtocol.TBinaryProtocolAccelerated(trans_fast)
|
|
|
112 |
prot_slow = TBinaryProtocol.TBinaryProtocol(trans_slow)
|
|
|
113 |
|
|
|
114 |
o.write(prot_fast)
|
|
|
115 |
o.write(prot_slow)
|
|
|
116 |
ORIG = trans_slow.getvalue()
|
|
|
117 |
MINE = trans_fast.getvalue()
|
|
|
118 |
if ORIG != MINE:
|
|
|
119 |
print "mine: %s\norig: %s" % (repr(MINE), repr(ORIG))
|
|
|
120 |
|
|
|
121 |
def checkRead(o):
|
|
|
122 |
prot = TBinaryProtocol.TBinaryProtocol(TTransport.TMemoryBuffer())
|
|
|
123 |
o.write(prot)
|
|
|
124 |
|
|
|
125 |
slow_version_binary = prot.trans.getvalue()
|
|
|
126 |
|
|
|
127 |
prot = TBinaryProtocol.TBinaryProtocolAccelerated(
|
|
|
128 |
TTransport.TMemoryBuffer(slow_version_binary))
|
|
|
129 |
c = o.__class__()
|
|
|
130 |
c.read(prot)
|
|
|
131 |
if c != o:
|
|
|
132 |
print "copy: "
|
|
|
133 |
pprint(eval(repr(c)))
|
|
|
134 |
print "orig: "
|
|
|
135 |
pprint(eval(repr(o)))
|
|
|
136 |
|
|
|
137 |
prot = TBinaryProtocol.TBinaryProtocolAccelerated(
|
|
|
138 |
TTransport.TBufferedTransport(
|
|
|
139 |
TTransport.TMemoryBuffer(slow_version_binary)))
|
|
|
140 |
c = o.__class__()
|
|
|
141 |
c.read(prot)
|
|
|
142 |
if c != o:
|
|
|
143 |
print "copy: "
|
|
|
144 |
pprint(eval(repr(c)))
|
|
|
145 |
print "orig: "
|
|
|
146 |
pprint(eval(repr(o)))
|
|
|
147 |
|
|
|
148 |
|
|
|
149 |
def doTest():
|
|
|
150 |
checkWrite(hm)
|
|
|
151 |
no_set = deepcopy(hm)
|
|
|
152 |
no_set.contain = set()
|
|
|
153 |
checkRead(no_set)
|
|
|
154 |
checkWrite(rs)
|
|
|
155 |
checkRead(rs)
|
|
|
156 |
checkWrite(rshuge)
|
|
|
157 |
checkRead(rshuge)
|
|
|
158 |
checkWrite(my_zero)
|
|
|
159 |
checkRead(my_zero)
|
|
|
160 |
checkRead(Backwards({"first_tag2":4, "second_tag1":2}))
|
|
|
161 |
|
|
|
162 |
# One case where the serialized form changes, but only superficially.
|
|
|
163 |
o = Backwards({"first_tag2":4, "second_tag1":2})
|
|
|
164 |
trans_fast = TTransport.TMemoryBuffer()
|
|
|
165 |
trans_slow = TTransport.TMemoryBuffer()
|
|
|
166 |
prot_fast = TBinaryProtocol.TBinaryProtocolAccelerated(trans_fast)
|
|
|
167 |
prot_slow = TBinaryProtocol.TBinaryProtocol(trans_slow)
|
|
|
168 |
|
|
|
169 |
o.write(prot_fast)
|
|
|
170 |
o.write(prot_slow)
|
|
|
171 |
ORIG = trans_slow.getvalue()
|
|
|
172 |
MINE = trans_fast.getvalue()
|
|
|
173 |
if ORIG == MINE:
|
|
|
174 |
print "That shouldn't happen."
|
|
|
175 |
|
|
|
176 |
|
|
|
177 |
prot = TBinaryProtocol.TBinaryProtocolAccelerated(TTransport.TMemoryBuffer())
|
|
|
178 |
o.write(prot)
|
|
|
179 |
prot = TBinaryProtocol.TBinaryProtocol(
|
|
|
180 |
TTransport.TMemoryBuffer(
|
|
|
181 |
prot.trans.getvalue()))
|
|
|
182 |
c = o.__class__()
|
|
|
183 |
c.read(prot)
|
|
|
184 |
if c != o:
|
|
|
185 |
print "copy: "
|
|
|
186 |
pprint(eval(repr(c)))
|
|
|
187 |
print "orig: "
|
|
|
188 |
pprint(eval(repr(o)))
|
|
|
189 |
|
|
|
190 |
|
|
|
191 |
|
|
|
192 |
def doBenchmark():
|
|
|
193 |
|
|
|
194 |
iters = 25000
|
|
|
195 |
|
|
|
196 |
setup = """
|
|
|
197 |
from __main__ import hm, rs, TDevNullTransport
|
|
|
198 |
from thrift.protocol import TBinaryProtocol
|
|
|
199 |
trans = TDevNullTransport()
|
|
|
200 |
prot = TBinaryProtocol.TBinaryProtocol%s(trans)
|
|
|
201 |
"""
|
|
|
202 |
|
|
|
203 |
setup_fast = setup % "Accelerated"
|
|
|
204 |
setup_slow = setup % ""
|
|
|
205 |
|
|
|
206 |
print "Starting Benchmarks"
|
|
|
207 |
|
|
|
208 |
print "HolyMoley Standard = %f" % \
|
|
|
209 |
timeit.Timer('hm.write(prot)', setup_slow).timeit(number=iters)
|
|
|
210 |
print "HolyMoley Acceler. = %f" % \
|
|
|
211 |
timeit.Timer('hm.write(prot)', setup_fast).timeit(number=iters)
|
|
|
212 |
|
|
|
213 |
print "FastStruct Standard = %f" % \
|
|
|
214 |
timeit.Timer('rs.write(prot)', setup_slow).timeit(number=iters)
|
|
|
215 |
print "FastStruct Acceler. = %f" % \
|
|
|
216 |
timeit.Timer('rs.write(prot)', setup_fast).timeit(number=iters)
|
|
|
217 |
|
|
|
218 |
|
|
|
219 |
|
|
|
220 |
doTest()
|
|
|
221 |
doBenchmark()
|
|
|
222 |
|