David Reiss | 382fc30 | 2007-08-25 18:01:30 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python |
David Reiss | ea2cba8 | 2009-03-30 21:35:00 +0000 | [diff] [blame] | 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 | |
David Reiss | 382fc30 | 2007-08-25 18:01:30 +0000 | [diff] [blame] | 22 | r""" |
David Reiss | 0c87ad4 | 2008-12-02 02:11:13 +0000 | [diff] [blame] | 23 | thrift --gen py DebugProtoTest.thrift |
David Reiss | 382fc30 | 2007-08-25 18:01:30 +0000 | [diff] [blame] | 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 | |
David Reiss | 2c2e6d2 | 2007-09-05 01:14:09 +0000 | [diff] [blame] | 102 | # make sure this splits two buffers in a buffered protocol |
| 103 | rshuge = RandomStuff() |
| 104 | rshuge.myintlist=range(10000) |
| 105 | |
David Reiss | 382fc30 | 2007-08-25 18:01:30 +0000 | [diff] [blame] | 106 | my_zero = Srv.Janky_result({"arg":5}) |
David Reiss | 382fc30 | 2007-08-25 18:01:30 +0000 | [diff] [blame] | 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) |
David Reiss | 2c2e6d2 | 2007-09-05 01:14:09 +0000 | [diff] [blame] | 124 | |
| 125 | slow_version_binary = prot.trans.getvalue() |
David Reiss | 0c90f6f | 2008-02-06 22:18:40 +0000 | [diff] [blame] | 126 | |
David Reiss | 382fc30 | 2007-08-25 18:01:30 +0000 | [diff] [blame] | 127 | prot = TBinaryProtocol.TBinaryProtocolAccelerated( |
David Reiss | 2c2e6d2 | 2007-09-05 01:14:09 +0000 | [diff] [blame] | 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))) |
David Reiss | 382fc30 | 2007-08-25 18:01:30 +0000 | [diff] [blame] | 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) |
David Reiss | 2c2e6d2 | 2007-09-05 01:14:09 +0000 | [diff] [blame] | 156 | checkWrite(rshuge) |
| 157 | checkRead(rshuge) |
David Reiss | 382fc30 | 2007-08-25 18:01:30 +0000 | [diff] [blame] | 158 | checkWrite(my_zero) |
| 159 | checkRead(my_zero) |
| 160 | checkRead(Backwards({"first_tag2":4, "second_tag1":2})) |
David Reiss | 382fc30 | 2007-08-25 18:01:30 +0000 | [diff] [blame] | 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 | |