1*1b3f573fSAndroid Build Coastguard Workerfrom __future__ import print_function 2*1b3f573fSAndroid Build Coastguard Workerimport sys 3*1b3f573fSAndroid Build Coastguard Workerimport os 4*1b3f573fSAndroid Build Coastguard Workerimport timeit 5*1b3f573fSAndroid Build Coastguard Workerimport math 6*1b3f573fSAndroid Build Coastguard Workerimport argparse 7*1b3f573fSAndroid Build Coastguard Workerimport fnmatch 8*1b3f573fSAndroid Build Coastguard Workerimport json 9*1b3f573fSAndroid Build Coastguard Worker 10*1b3f573fSAndroid Build Coastguard Workerparser = argparse.ArgumentParser(description="Python protobuf benchmark") 11*1b3f573fSAndroid Build Coastguard Workerparser.add_argument("data_files", metavar="dataFile", nargs="+", 12*1b3f573fSAndroid Build Coastguard Worker help="testing data files.") 13*1b3f573fSAndroid Build Coastguard Workerparser.add_argument("--json", action="store_const", dest="json", 14*1b3f573fSAndroid Build Coastguard Worker const="yes", default="no", 15*1b3f573fSAndroid Build Coastguard Worker help="Whether to output json results") 16*1b3f573fSAndroid Build Coastguard Workerparser.add_argument("--behavior_prefix", dest="behavior_prefix", 17*1b3f573fSAndroid Build Coastguard Worker help="The output json format's behavior's name's prefix", 18*1b3f573fSAndroid Build Coastguard Worker default="") 19*1b3f573fSAndroid Build Coastguard Worker# BEGIN CPP GENERATED MESSAGE 20*1b3f573fSAndroid Build Coastguard Workerparser.add_argument("--cpp_generated", action="store_const", 21*1b3f573fSAndroid Build Coastguard Worker dest="cpp_generated", const="yes", default="no", 22*1b3f573fSAndroid Build Coastguard Worker help="Whether to link generated code library") 23*1b3f573fSAndroid Build Coastguard Worker# END CPP GENERATED MESSAGE 24*1b3f573fSAndroid Build Coastguard Workerargs = parser.parse_args() 25*1b3f573fSAndroid Build Coastguard Worker# BEGIN CPP GENERATED MESSAGE 26*1b3f573fSAndroid Build Coastguard Worker# CPP generated code must be linked before importing the generated Python code 27*1b3f573fSAndroid Build Coastguard Worker# for the descriptor can be found in the pool 28*1b3f573fSAndroid Build Coastguard Workerif args.cpp_generated != "no": 29*1b3f573fSAndroid Build Coastguard Worker sys.path.append( os.path.dirname( os.path.dirname( os.path.abspath(__file__) ) ) + "/.libs" ) 30*1b3f573fSAndroid Build Coastguard Worker import libbenchmark_messages 31*1b3f573fSAndroid Build Coastguard Worker sys.path.append( os.path.dirname( os.path.dirname( os.path.abspath(__file__) ) ) + "/tmp" ) 32*1b3f573fSAndroid Build Coastguard Worker# END CPP GENERATED MESSAGE 33*1b3f573fSAndroid Build Coastguard Worker 34*1b3f573fSAndroid Build Coastguard Worker 35*1b3f573fSAndroid Build Coastguard Workerimport datasets.google_message1.proto2.benchmark_message1_proto2_pb2 as benchmark_message1_proto2_pb2 36*1b3f573fSAndroid Build Coastguard Workerimport datasets.google_message1.proto3.benchmark_message1_proto3_pb2 as benchmark_message1_proto3_pb2 37*1b3f573fSAndroid Build Coastguard Workerimport datasets.google_message2.benchmark_message2_pb2 as benchmark_message2_pb2 38*1b3f573fSAndroid Build Coastguard Workerimport datasets.google_message3.benchmark_message3_pb2 as benchmark_message3_pb2 39*1b3f573fSAndroid Build Coastguard Workerimport datasets.google_message4.benchmark_message4_pb2 as benchmark_message4_pb2 40*1b3f573fSAndroid Build Coastguard Workerimport benchmarks_pb2 as benchmarks_pb2 41*1b3f573fSAndroid Build Coastguard Worker 42*1b3f573fSAndroid Build Coastguard Worker 43*1b3f573fSAndroid Build Coastguard Workerdef run_one_test(filename): 44*1b3f573fSAndroid Build Coastguard Worker data = open(filename, "rb").read() 45*1b3f573fSAndroid Build Coastguard Worker benchmark_dataset = benchmarks_pb2.BenchmarkDataset() 46*1b3f573fSAndroid Build Coastguard Worker benchmark_dataset.ParseFromString(data) 47*1b3f573fSAndroid Build Coastguard Worker total_bytes = 0 48*1b3f573fSAndroid Build Coastguard Worker for payload in benchmark_dataset.payload: 49*1b3f573fSAndroid Build Coastguard Worker total_bytes += len(payload) 50*1b3f573fSAndroid Build Coastguard Worker benchmark_util = Benchmark(full_iteration=len(benchmark_dataset.payload), 51*1b3f573fSAndroid Build Coastguard Worker module="py_benchmark", 52*1b3f573fSAndroid Build Coastguard Worker setup_method="init", 53*1b3f573fSAndroid Build Coastguard Worker total_bytes=total_bytes) 54*1b3f573fSAndroid Build Coastguard Worker result={} 55*1b3f573fSAndroid Build Coastguard Worker result["filename"] = filename 56*1b3f573fSAndroid Build Coastguard Worker result["message_name"] = benchmark_dataset.message_name 57*1b3f573fSAndroid Build Coastguard Worker result["benchmarks"] = {} 58*1b3f573fSAndroid Build Coastguard Worker benchmark_util.set_test_method("parse_from_benchmark") 59*1b3f573fSAndroid Build Coastguard Worker result["benchmarks"][args.behavior_prefix + "_parse_from_benchmark"] = \ 60*1b3f573fSAndroid Build Coastguard Worker benchmark_util.run_benchmark(setup_method_args='"%s"' % (filename)) 61*1b3f573fSAndroid Build Coastguard Worker benchmark_util.set_test_method("serialize_to_benchmark") 62*1b3f573fSAndroid Build Coastguard Worker result["benchmarks"][args.behavior_prefix + "_serialize_to_benchmark"] = \ 63*1b3f573fSAndroid Build Coastguard Worker benchmark_util.run_benchmark(setup_method_args='"%s"' % (filename)) 64*1b3f573fSAndroid Build Coastguard Worker return result 65*1b3f573fSAndroid Build Coastguard Worker 66*1b3f573fSAndroid Build Coastguard Worker 67*1b3f573fSAndroid Build Coastguard Workerdef init(filename): 68*1b3f573fSAndroid Build Coastguard Worker global benchmark_dataset, message_class, message_list, counter, total_bytes 69*1b3f573fSAndroid Build Coastguard Worker message_list=[] 70*1b3f573fSAndroid Build Coastguard Worker counter = 0 71*1b3f573fSAndroid Build Coastguard Worker total_bytes = 0 72*1b3f573fSAndroid Build Coastguard Worker data = open(filename, "rb").read() 73*1b3f573fSAndroid Build Coastguard Worker benchmark_dataset = benchmarks_pb2.BenchmarkDataset() 74*1b3f573fSAndroid Build Coastguard Worker benchmark_dataset.ParseFromString(data) 75*1b3f573fSAndroid Build Coastguard Worker 76*1b3f573fSAndroid Build Coastguard Worker if benchmark_dataset.message_name == "benchmarks.proto3.GoogleMessage1": 77*1b3f573fSAndroid Build Coastguard Worker message_class = benchmark_message1_proto3_pb2.GoogleMessage1 78*1b3f573fSAndroid Build Coastguard Worker elif benchmark_dataset.message_name == "benchmarks.proto2.GoogleMessage1": 79*1b3f573fSAndroid Build Coastguard Worker message_class = benchmark_message1_proto2_pb2.GoogleMessage1 80*1b3f573fSAndroid Build Coastguard Worker elif benchmark_dataset.message_name == "benchmarks.proto2.GoogleMessage2": 81*1b3f573fSAndroid Build Coastguard Worker message_class = benchmark_message2_pb2.GoogleMessage2 82*1b3f573fSAndroid Build Coastguard Worker elif benchmark_dataset.message_name == "benchmarks.google_message3.GoogleMessage3": 83*1b3f573fSAndroid Build Coastguard Worker message_class = benchmark_message3_pb2.GoogleMessage3 84*1b3f573fSAndroid Build Coastguard Worker elif benchmark_dataset.message_name == "benchmarks.google_message4.GoogleMessage4": 85*1b3f573fSAndroid Build Coastguard Worker message_class = benchmark_message4_pb2.GoogleMessage4 86*1b3f573fSAndroid Build Coastguard Worker else: 87*1b3f573fSAndroid Build Coastguard Worker raise IOError("Message %s not found!" % (benchmark_dataset.message_name)) 88*1b3f573fSAndroid Build Coastguard Worker 89*1b3f573fSAndroid Build Coastguard Worker for one_payload in benchmark_dataset.payload: 90*1b3f573fSAndroid Build Coastguard Worker temp = message_class() 91*1b3f573fSAndroid Build Coastguard Worker temp.ParseFromString(one_payload) 92*1b3f573fSAndroid Build Coastguard Worker message_list.append(temp) 93*1b3f573fSAndroid Build Coastguard Worker total_bytes += len(one_payload) 94*1b3f573fSAndroid Build Coastguard Worker 95*1b3f573fSAndroid Build Coastguard Worker 96*1b3f573fSAndroid Build Coastguard Workerdef parse_from_benchmark(): 97*1b3f573fSAndroid Build Coastguard Worker global counter, message_class, benchmark_dataset 98*1b3f573fSAndroid Build Coastguard Worker m = message_class().ParseFromString(benchmark_dataset.payload[counter % len(benchmark_dataset.payload)]) 99*1b3f573fSAndroid Build Coastguard Worker counter = counter + 1 100*1b3f573fSAndroid Build Coastguard Worker 101*1b3f573fSAndroid Build Coastguard Worker 102*1b3f573fSAndroid Build Coastguard Workerdef serialize_to_benchmark(): 103*1b3f573fSAndroid Build Coastguard Worker global counter, message_list, message_class 104*1b3f573fSAndroid Build Coastguard Worker s = message_list[counter % len(benchmark_dataset.payload)].SerializeToString() 105*1b3f573fSAndroid Build Coastguard Worker counter = counter + 1 106*1b3f573fSAndroid Build Coastguard Worker 107*1b3f573fSAndroid Build Coastguard Worker 108*1b3f573fSAndroid Build Coastguard Workerclass Benchmark: 109*1b3f573fSAndroid Build Coastguard Worker def __init__(self, module=None, test_method=None, 110*1b3f573fSAndroid Build Coastguard Worker setup_method=None, total_bytes=None, full_iteration = 1): 111*1b3f573fSAndroid Build Coastguard Worker self.full_iteration = full_iteration 112*1b3f573fSAndroid Build Coastguard Worker self.module = module 113*1b3f573fSAndroid Build Coastguard Worker self.test_method = test_method 114*1b3f573fSAndroid Build Coastguard Worker self.setup_method = setup_method 115*1b3f573fSAndroid Build Coastguard Worker self.total_bytes = total_bytes 116*1b3f573fSAndroid Build Coastguard Worker 117*1b3f573fSAndroid Build Coastguard Worker def set_test_method(self, test_method): 118*1b3f573fSAndroid Build Coastguard Worker self.test_method = test_method 119*1b3f573fSAndroid Build Coastguard Worker 120*1b3f573fSAndroid Build Coastguard Worker def full_setup_code(self, setup_method_args=''): 121*1b3f573fSAndroid Build Coastguard Worker setup_code = "" 122*1b3f573fSAndroid Build Coastguard Worker setup_code += "from %s import %s\n" % (self.module, self.test_method) 123*1b3f573fSAndroid Build Coastguard Worker setup_code += "from %s import %s\n" % (self.module, self.setup_method) 124*1b3f573fSAndroid Build Coastguard Worker setup_code += "%s(%s)\n" % (self.setup_method, setup_method_args) 125*1b3f573fSAndroid Build Coastguard Worker return setup_code 126*1b3f573fSAndroid Build Coastguard Worker 127*1b3f573fSAndroid Build Coastguard Worker def dry_run(self, test_method_args='', setup_method_args=''): 128*1b3f573fSAndroid Build Coastguard Worker return timeit.timeit(stmt="%s(%s)" % (self.test_method, test_method_args), 129*1b3f573fSAndroid Build Coastguard Worker setup=self.full_setup_code(setup_method_args), 130*1b3f573fSAndroid Build Coastguard Worker number=self.full_iteration); 131*1b3f573fSAndroid Build Coastguard Worker 132*1b3f573fSAndroid Build Coastguard Worker def run_benchmark(self, test_method_args='', setup_method_args=''): 133*1b3f573fSAndroid Build Coastguard Worker reps = self.full_iteration; 134*1b3f573fSAndroid Build Coastguard Worker t = self.dry_run(test_method_args, setup_method_args); 135*1b3f573fSAndroid Build Coastguard Worker if t < 3 : 136*1b3f573fSAndroid Build Coastguard Worker reps = int(math.ceil(3 / t)) * self.full_iteration 137*1b3f573fSAndroid Build Coastguard Worker if reps != self.full_iteration: 138*1b3f573fSAndroid Build Coastguard Worker t = timeit.timeit(stmt="%s(%s)" % (self.test_method, test_method_args), 139*1b3f573fSAndroid Build Coastguard Worker setup=self.full_setup_code(setup_method_args), 140*1b3f573fSAndroid Build Coastguard Worker number=reps); 141*1b3f573fSAndroid Build Coastguard Worker return self.total_bytes * 1.0 / 2 ** 20 / (1.0 * t / reps * self.full_iteration) 142*1b3f573fSAndroid Build Coastguard Worker 143*1b3f573fSAndroid Build Coastguard Worker 144*1b3f573fSAndroid Build Coastguard Workerif __name__ == "__main__": 145*1b3f573fSAndroid Build Coastguard Worker results = [] 146*1b3f573fSAndroid Build Coastguard Worker for file in args.data_files: 147*1b3f573fSAndroid Build Coastguard Worker results.append(run_one_test(file)) 148*1b3f573fSAndroid Build Coastguard Worker 149*1b3f573fSAndroid Build Coastguard Worker if args.json != "no": 150*1b3f573fSAndroid Build Coastguard Worker print(json.dumps(results)) 151*1b3f573fSAndroid Build Coastguard Worker else: 152*1b3f573fSAndroid Build Coastguard Worker for result in results: 153*1b3f573fSAndroid Build Coastguard Worker print("Message %s of dataset file %s" % \ 154*1b3f573fSAndroid Build Coastguard Worker (result["message_name"], result["filename"])) 155*1b3f573fSAndroid Build Coastguard Worker print("Average throughput for parse_from_benchmark: %.2f MB/s" % \ 156*1b3f573fSAndroid Build Coastguard Worker (result["benchmarks"][ \ 157*1b3f573fSAndroid Build Coastguard Worker args.behavior_prefix + "_parse_from_benchmark"])) 158*1b3f573fSAndroid Build Coastguard Worker print("Average throughput for serialize_to_benchmark: %.2f MB/s" % \ 159*1b3f573fSAndroid Build Coastguard Worker (result["benchmarks"][ \ 160*1b3f573fSAndroid Build Coastguard Worker args.behavior_prefix + "_serialize_to_benchmark"])) 161*1b3f573fSAndroid Build Coastguard Worker print("") 162