2007-08-25 18:01:30 +00:00
|
|
|
#!/usr/bin/env python
|
2009-03-30 21:35:00 +00:00
|
|
|
|
|
|
|
#
|
|
|
|
# Licensed to the Apache Software Foundation (ASF) under one
|
|
|
|
# or more contributor license agreements. See the NOTICE file
|
|
|
|
# distributed with this work for additional information
|
|
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
|
|
# to you under the Apache License, Version 2.0 (the
|
|
|
|
# "License"); you may not use this file except in compliance
|
|
|
|
# with the License. You may obtain a copy of the License at
|
|
|
|
#
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
#
|
|
|
|
# Unless required by applicable law or agreed to in writing,
|
|
|
|
# software distributed under the License is distributed on an
|
|
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
|
|
# KIND, either express or implied. See the License for the
|
|
|
|
# specific language governing permissions and limitations
|
|
|
|
# under the License.
|
|
|
|
#
|
|
|
|
|
2007-08-25 18:01:30 +00:00
|
|
|
r"""
|
2015-12-23 12:45:06 +00:00
|
|
|
PYTHONPATH=./gen-py:../../lib/py/build/lib... ./FastbinaryTest.py
|
2007-08-25 18:01:30 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
# TODO(dreiss): Test error cases. Check for memory leaks.
|
|
|
|
|
2016-02-11 04:58:39 +00:00
|
|
|
from __future__ import print_function
|
|
|
|
|
2007-08-25 18:01:30 +00:00
|
|
|
import math
|
2016-01-06 11:44:17 +00:00
|
|
|
import os
|
|
|
|
import sys
|
2007-08-25 18:01:30 +00:00
|
|
|
import timeit
|
2015-12-23 12:45:06 +00:00
|
|
|
|
2007-08-25 18:01:30 +00:00
|
|
|
from copy import deepcopy
|
|
|
|
from pprint import pprint
|
|
|
|
|
2015-12-23 12:45:06 +00:00
|
|
|
from thrift.transport import TTransport
|
2016-02-11 04:58:39 +00:00
|
|
|
from thrift.protocol.TBinaryProtocol import TBinaryProtocol, TBinaryProtocolAccelerated
|
|
|
|
from thrift.protocol.TCompactProtocol import TCompactProtocol, TCompactProtocolAccelerated
|
2015-12-23 12:45:06 +00:00
|
|
|
|
|
|
|
from DebugProtoTest import Srv
|
|
|
|
from DebugProtoTest.ttypes import Backwards, Bonk, Empty, HolyMoley, OneOfEach, RandomStuff, Wrapper
|
|
|
|
|
|
|
|
|
2007-08-25 18:01:30 +00:00
|
|
|
class TDevNullTransport(TTransport.TTransportBase):
|
2016-02-02 16:57:03 +00:00
|
|
|
def __init__(self):
|
|
|
|
pass
|
2015-12-23 12:45:06 +00:00
|
|
|
|
2016-02-02 16:57:03 +00:00
|
|
|
def isOpen(self):
|
|
|
|
return True
|
2007-08-25 18:01:30 +00:00
|
|
|
|
|
|
|
ooe1 = OneOfEach()
|
2015-12-23 12:45:06 +00:00
|
|
|
ooe1.im_true = True
|
|
|
|
ooe1.im_false = False
|
|
|
|
ooe1.a_bite = 0xd6
|
|
|
|
ooe1.integer16 = 27000
|
|
|
|
ooe1.integer32 = 1 << 24
|
|
|
|
ooe1.integer64 = 6000 * 1000 * 1000
|
|
|
|
ooe1.double_precision = math.pi
|
|
|
|
ooe1.some_characters = "Debug THIS!"
|
2016-01-06 11:44:17 +00:00
|
|
|
ooe1.zomg_unicode = u"\xd7\n\a\t"
|
2015-12-23 12:45:06 +00:00
|
|
|
|
|
|
|
ooe2 = OneOfEach()
|
|
|
|
ooe2.integer16 = 16
|
|
|
|
ooe2.integer32 = 32
|
|
|
|
ooe2.integer64 = 64
|
|
|
|
ooe2.double_precision = (math.sqrt(5) + 1) / 2
|
|
|
|
ooe2.some_characters = ":R (me going \"rrrr\")"
|
2016-01-06 11:44:17 +00:00
|
|
|
ooe2.zomg_unicode = u"\xd3\x80\xe2\x85\xae\xce\x9d\x20"\
|
|
|
|
u"\xd0\x9d\xce\xbf\xe2\x85\xbf\xd0\xbe"\
|
|
|
|
u"\xc9\xa1\xd0\xb3\xd0\xb0\xcf\x81\xe2\x84\x8e"\
|
|
|
|
u"\x20\xce\x91\x74\x74\xce\xb1\xe2\x85\xbd\xce\xba"\
|
|
|
|
u"\xc7\x83\xe2\x80\xbc"
|
|
|
|
|
|
|
|
if sys.version_info[0] == 2 and os.environ.get('THRIFT_TEST_PY_NO_UTF8STRINGS'):
|
2016-02-02 16:57:03 +00:00
|
|
|
ooe1.zomg_unicode = ooe1.zomg_unicode.encode('utf8')
|
|
|
|
ooe2.zomg_unicode = ooe2.zomg_unicode.encode('utf8')
|
2015-12-23 12:45:06 +00:00
|
|
|
|
|
|
|
hm = HolyMoley(**{"big": [], "contain": set(), "bonks": {}})
|
2007-08-25 18:01:30 +00:00
|
|
|
hm.big.append(ooe1)
|
|
|
|
hm.big.append(ooe2)
|
2015-12-23 12:45:06 +00:00
|
|
|
hm.big[0].a_bite = 0x22
|
|
|
|
hm.big[1].a_bite = 0x22
|
2007-08-25 18:01:30 +00:00
|
|
|
|
|
|
|
hm.contain.add(("and a one", "and a two"))
|
|
|
|
hm.contain.add(("then a one, two", "three!", "FOUR!"))
|
2017-05-23 15:36:23 +00:00
|
|
|
if sys.version_info[0] == 2 and os.environ.get('THRIFT_TEST_PY_NO_UTF8STRINGS'):
|
|
|
|
hm.contain.add((u"\xd7\n\a\t".encode('utf8'),))
|
|
|
|
else:
|
|
|
|
hm.contain.add((u"\xd7\n\a\t",))
|
2007-08-25 18:01:30 +00:00
|
|
|
hm.contain.add(())
|
|
|
|
|
2015-12-23 12:45:06 +00:00
|
|
|
hm.bonks["nothing"] = []
|
2007-08-25 18:01:30 +00:00
|
|
|
hm.bonks["something"] = [
|
2016-02-02 16:57:03 +00:00
|
|
|
Bonk(**{"type": 1, "message": "Wait."}),
|
|
|
|
Bonk(**{"type": 2, "message": "What?"}),
|
2007-08-25 18:01:30 +00:00
|
|
|
]
|
|
|
|
hm.bonks["poe"] = [
|
2016-02-02 16:57:03 +00:00
|
|
|
Bonk(**{"type": 3, "message": "quoth"}),
|
|
|
|
Bonk(**{"type": 4, "message": "the raven"}),
|
|
|
|
Bonk(**{"type": 5, "message": "nevermore"}),
|
2007-08-25 18:01:30 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
rs = RandomStuff()
|
|
|
|
rs.a = 1
|
|
|
|
rs.b = 2
|
|
|
|
rs.c = 3
|
2016-02-11 04:58:39 +00:00
|
|
|
rs.myintlist = list(range(20))
|
2015-12-23 12:45:06 +00:00
|
|
|
rs.maps = {1: Wrapper(**{"foo": Empty()}), 2: Wrapper(**{"foo": Empty()})}
|
|
|
|
rs.bigint = 124523452435
|
2007-08-25 18:01:30 +00:00
|
|
|
rs.triple = 3.14
|
|
|
|
|
2007-09-05 01:14:09 +00:00
|
|
|
# make sure this splits two buffers in a buffered protocol
|
|
|
|
rshuge = RandomStuff()
|
2016-02-11 04:58:39 +00:00
|
|
|
rshuge.myintlist = list(range(10000))
|
2015-12-23 12:45:06 +00:00
|
|
|
|
|
|
|
my_zero = Srv.Janky_result(**{"success": 5})
|
2007-09-05 01:14:09 +00:00
|
|
|
|
2007-08-25 18:01:30 +00:00
|
|
|
|
2016-02-11 04:58:39 +00:00
|
|
|
class Test(object):
|
|
|
|
def __init__(self, fast, slow):
|
|
|
|
self._fast = fast
|
|
|
|
self._slow = slow
|
|
|
|
|
|
|
|
def _check_write(self, o):
|
|
|
|
trans_fast = TTransport.TMemoryBuffer()
|
|
|
|
trans_slow = TTransport.TMemoryBuffer()
|
2016-02-11 07:21:01 +00:00
|
|
|
prot_fast = self._fast(trans_fast, fallback=False)
|
2016-02-11 04:58:39 +00:00
|
|
|
prot_slow = self._slow(trans_slow)
|
|
|
|
|
|
|
|
o.write(prot_fast)
|
|
|
|
o.write(prot_slow)
|
|
|
|
ORIG = trans_slow.getvalue()
|
|
|
|
MINE = trans_fast.getvalue()
|
|
|
|
if ORIG != MINE:
|
|
|
|
print("actual : %s\nexpected: %s" % (repr(MINE), repr(ORIG)))
|
|
|
|
raise Exception('write value mismatch')
|
|
|
|
|
|
|
|
def _check_read(self, o):
|
|
|
|
prot = self._slow(TTransport.TMemoryBuffer())
|
|
|
|
o.write(prot)
|
|
|
|
|
|
|
|
slow_version_binary = prot.trans.getvalue()
|
|
|
|
|
|
|
|
prot = self._fast(
|
2016-02-11 07:21:01 +00:00
|
|
|
TTransport.TMemoryBuffer(slow_version_binary), fallback=False)
|
2016-02-11 04:58:39 +00:00
|
|
|
c = o.__class__()
|
|
|
|
c.read(prot)
|
|
|
|
if c != o:
|
|
|
|
print("actual : ")
|
|
|
|
pprint(repr(c))
|
|
|
|
print("expected: ")
|
|
|
|
pprint(repr(o))
|
|
|
|
raise Exception('read value mismatch')
|
|
|
|
|
|
|
|
prot = self._fast(
|
|
|
|
TTransport.TBufferedTransport(
|
2016-02-11 07:21:01 +00:00
|
|
|
TTransport.TMemoryBuffer(slow_version_binary)), fallback=False)
|
2016-02-11 04:58:39 +00:00
|
|
|
c = o.__class__()
|
|
|
|
c.read(prot)
|
|
|
|
if c != o:
|
|
|
|
print("actual : ")
|
|
|
|
pprint(repr(c))
|
|
|
|
print("expected: ")
|
|
|
|
pprint(repr(o))
|
|
|
|
raise Exception('read value mismatch')
|
|
|
|
|
|
|
|
def do_test(self):
|
|
|
|
self._check_write(HolyMoley())
|
|
|
|
self._check_read(HolyMoley())
|
|
|
|
|
|
|
|
self._check_write(hm)
|
|
|
|
no_set = deepcopy(hm)
|
|
|
|
no_set.contain = set()
|
|
|
|
self._check_read(no_set)
|
|
|
|
self._check_read(hm)
|
|
|
|
|
|
|
|
self._check_write(rs)
|
|
|
|
self._check_read(rs)
|
|
|
|
|
|
|
|
self._check_write(rshuge)
|
|
|
|
self._check_read(rshuge)
|
|
|
|
|
|
|
|
self._check_write(my_zero)
|
|
|
|
self._check_read(my_zero)
|
|
|
|
|
|
|
|
self._check_read(Backwards(**{"first_tag2": 4, "second_tag1": 2}))
|
|
|
|
|
|
|
|
# One case where the serialized form changes, but only superficially.
|
|
|
|
o = Backwards(**{"first_tag2": 4, "second_tag1": 2})
|
|
|
|
trans_fast = TTransport.TMemoryBuffer()
|
|
|
|
trans_slow = TTransport.TMemoryBuffer()
|
2016-02-11 07:21:01 +00:00
|
|
|
prot_fast = self._fast(trans_fast, fallback=False)
|
2016-02-11 04:58:39 +00:00
|
|
|
prot_slow = self._slow(trans_slow)
|
|
|
|
|
|
|
|
o.write(prot_fast)
|
|
|
|
o.write(prot_slow)
|
|
|
|
ORIG = trans_slow.getvalue()
|
|
|
|
MINE = trans_fast.getvalue()
|
|
|
|
assert id(ORIG) != id(MINE)
|
|
|
|
|
2016-02-11 07:21:01 +00:00
|
|
|
prot = self._fast(TTransport.TMemoryBuffer(), fallback=False)
|
2016-02-11 04:58:39 +00:00
|
|
|
o.write(prot)
|
|
|
|
prot = self._slow(
|
|
|
|
TTransport.TMemoryBuffer(prot.trans.getvalue()))
|
|
|
|
c = o.__class__()
|
|
|
|
c.read(prot)
|
|
|
|
if c != o:
|
|
|
|
print("copy: ")
|
|
|
|
pprint(repr(c))
|
|
|
|
print("orig: ")
|
|
|
|
pprint(repr(o))
|
|
|
|
|
|
|
|
|
|
|
|
def do_test(fast, slow):
|
|
|
|
Test(fast, slow).do_test()
|
|
|
|
|
|
|
|
|
|
|
|
def do_benchmark(protocol, iters=5000, skip_slow=False):
|
2016-02-02 16:57:03 +00:00
|
|
|
setup = """
|
2007-08-25 18:01:30 +00:00
|
|
|
from __main__ import hm, rs, TDevNullTransport
|
2016-02-11 04:58:39 +00:00
|
|
|
from thrift.protocol.{0} import {0}{1}
|
2007-08-25 18:01:30 +00:00
|
|
|
trans = TDevNullTransport()
|
2016-02-11 07:21:01 +00:00
|
|
|
prot = {0}{1}(trans{2})
|
2007-08-25 18:01:30 +00:00
|
|
|
"""
|
|
|
|
|
2016-02-11 07:21:01 +00:00
|
|
|
setup_fast = setup.format(protocol, 'Accelerated', ', fallback=False')
|
2016-02-11 04:58:39 +00:00
|
|
|
if not skip_slow:
|
2016-02-11 07:21:01 +00:00
|
|
|
setup_slow = setup.format(protocol, '', '')
|
2007-08-25 18:01:30 +00:00
|
|
|
|
2016-02-02 16:57:03 +00:00
|
|
|
print("Starting Benchmarks")
|
2007-08-25 18:01:30 +00:00
|
|
|
|
2016-02-11 04:58:39 +00:00
|
|
|
if not skip_slow:
|
|
|
|
print("HolyMoley Standard = %f" %
|
|
|
|
timeit.Timer('hm.write(prot)', setup_slow).timeit(number=iters))
|
|
|
|
|
2016-02-02 16:57:03 +00:00
|
|
|
print("HolyMoley Acceler. = %f" %
|
|
|
|
timeit.Timer('hm.write(prot)', setup_fast).timeit(number=iters))
|
2007-08-25 18:01:30 +00:00
|
|
|
|
2016-02-11 04:58:39 +00:00
|
|
|
if not skip_slow:
|
|
|
|
print("FastStruct Standard = %f" %
|
|
|
|
timeit.Timer('rs.write(prot)', setup_slow).timeit(number=iters))
|
|
|
|
|
2016-02-02 16:57:03 +00:00
|
|
|
print("FastStruct Acceler. = %f" %
|
|
|
|
timeit.Timer('rs.write(prot)', setup_fast).timeit(number=iters))
|
2007-08-25 18:01:30 +00:00
|
|
|
|
2016-02-11 04:58:39 +00:00
|
|
|
|
2015-12-23 12:45:06 +00:00
|
|
|
if __name__ == '__main__':
|
2016-02-11 04:58:39 +00:00
|
|
|
print('Testing TBinaryAccelerated')
|
|
|
|
do_test(TBinaryProtocolAccelerated, TBinaryProtocol)
|
|
|
|
do_benchmark('TBinaryProtocol')
|
|
|
|
print('Testing TCompactAccelerated')
|
|
|
|
do_test(TCompactProtocolAccelerated, TCompactProtocol)
|
|
|
|
do_benchmark('TCompactProtocol')
|