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