123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- # This import depends on the automake rule protoc_middleman, please make sure
- # protoc_middleman has been built before run this file.
- import argparse
- import json
- import re
- import os.path
- # BEGIN OPENSOURCE
- import sys
- sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))
- # END OPENSOURCE
- import tmp.benchmarks_pb2 as benchmarks_pb2
- __file_size_map = {}
- def __get_data_size(filename):
- if filename[0] != '/':
- filename = os.path.dirname(os.path.abspath(__file__)) + "/../" + filename
- if filename in __file_size_map:
- return __file_size_map[filename]
- benchmark_dataset = benchmarks_pb2.BenchmarkDataset()
- benchmark_dataset.ParseFromString(
- open(filename, "rb").read())
- size = 0
- count = 0
- for payload in benchmark_dataset.payload:
- size += len(payload)
- count += 1
- __file_size_map[filename] = (size, 1.0 * size / count)
- return size, 1.0 * size / count
- def __extract_file_name(file_name):
- name_list = re.split(r"[/\.]", file_name)
- short_file_name = ""
- for name in name_list:
- if name[:14] == "google_message":
- short_file_name = name
- return short_file_name
- __results = []
- # CPP results example:
- # [
- # "benchmarks": [
- # {
- # "bytes_per_second": int,
- # "cpu_time_ns": double,
- # "iterations": int,
- # "name: string,
- # "real_time_ns: double,
- # ...
- # },
- # ...
- # ],
- # ...
- # ]
- def __parse_cpp_result(filename):
- if filename == "":
- return
- if filename[0] != '/':
- filename = os.path.dirname(os.path.abspath(__file__)) + '/' + filename
- with open(filename, encoding="utf-8") as f:
- results = json.loads(f.read())
- for benchmark in results["benchmarks"]:
- data_filename = "".join(
- re.split("(_parse_|_serialize)", benchmark["name"])[0])
- behavior = benchmark["name"][len(data_filename) + 1:]
- if data_filename[:2] == "BM":
- data_filename = data_filename[3:]
- __results.append({
- "language": "cpp",
- "dataFilename": data_filename,
- "behavior": behavior,
- "throughput": benchmark["bytes_per_second"] / 2.0 ** 20
- })
- # Synthetic benchmark results example:
- # [
- # "benchmarks": [
- # {
- # "cpu_time_ns": double,
- # "iterations": int,
- # "name: string,
- # "real_time_ns: double,
- # ...
- # },
- # ...
- # ],
- # ...
- # ]
- def __parse_synthetic_result(filename):
- if filename == "":
- return
- if filename[0] != "/":
- filename = os.path.dirname(os.path.abspath(__file__)) + "/" + filename
- with open(filename, encoding="utf-8") as f:
- results = json.loads(f.read())
- for benchmark in results["benchmarks"]:
- __results.append({
- "language": "cpp",
- "dataFilename": "",
- "behavior": "synthetic",
- "throughput": 10.0**9 / benchmark["cpu_time_ns"]
- })
- # Python results example:
- # [
- # [
- # {
- # "filename": string,
- # "benchmarks": {
- # behavior: results,
- # ...
- # },
- # },
- # ...
- # ], #pure-python
- # ...
- # ]
- def __parse_python_result(filename):
- if filename == "":
- return
- if filename[0] != '/':
- filename = os.path.dirname(os.path.abspath(__file__)) + '/' + filename
- with open(filename, encoding="utf-8") as f:
- results_list = json.loads(f.read())
- for results in results_list:
- for result in results:
- _, avg_size = __get_data_size(result["filename"])
- for behavior in result["benchmarks"]:
- __results.append({
- "language": "python",
- "dataFilename": __extract_file_name(result["filename"]),
- "behavior": behavior,
- "throughput": result["benchmarks"][behavior]
- })
- # Java results example:
- # [
- # {
- # "id": string,
- # "instrumentSpec": {...},
- # "measurements": [
- # {
- # "weight": float,
- # "value": {
- # "magnitude": float,
- # "unit": string
- # },
- # ...
- # },
- # ...
- # ],
- # "run": {...},
- # "scenario": {
- # "benchmarkSpec": {
- # "methodName": string,
- # "parameters": {
- # defined parameters in the benchmark: parameters value
- # },
- # ...
- # },
- # ...
- # }
- #
- # },
- # ...
- # ]
- def __parse_java_result(filename):
- if filename == "":
- return
- if filename[0] != '/':
- filename = os.path.dirname(os.path.abspath(__file__)) + '/' + filename
- with open(filename, encoding="utf-8") as f:
- results = json.loads(f.read())
- for result in results:
- total_weight = 0
- total_value = 0
- for measurement in result["measurements"]:
- total_weight += measurement["weight"]
- total_value += measurement["value"]["magnitude"]
- avg_time = total_value * 1.0 / total_weight
- total_size, _ = __get_data_size(
- result["scenario"]["benchmarkSpec"]["parameters"]["dataFile"])
- __results.append({
- "language": "java",
- "throughput": total_size / avg_time * 1e9 / 2 ** 20,
- "behavior": result["scenario"]["benchmarkSpec"]["methodName"],
- "dataFilename": __extract_file_name(
- result["scenario"]["benchmarkSpec"]["parameters"]["dataFile"])
- })
- # Go benchmark results:
- #
- # goos: linux
- # goarch: amd64
- # Benchmark/.././datasets/google_message2/dataset.google_message2.pb/Unmarshal-12 3000 705784 ns/op
- # Benchmark/.././datasets/google_message2/dataset.google_message2.pb/Marshal-12 2000 634648 ns/op
- # Benchmark/.././datasets/google_message2/dataset.google_message2.pb/Size-12 5000 244174 ns/op
- # Benchmark/.././datasets/google_message2/dataset.google_message2.pb/Clone-12 300 4120954 ns/op
- # Benchmark/.././datasets/google_message2/dataset.google_message2.pb/Merge-12 300 4108632 ns/op
- # PASS
- # ok _/usr/local/google/home/yilunchong/mygit/protobuf/benchmarks 124.173s
- def __parse_go_result(filename):
- if filename == "":
- return
- if filename[0] != '/':
- filename = os.path.dirname(os.path.abspath(__file__)) + '/' + filename
- with open(filename, encoding="utf-8") as f:
- for line in f:
- result_list = re.split(r"[\ \t]+", line)
- if result_list[0][:9] != "Benchmark":
- continue
- first_slash_index = result_list[0].find('/')
- last_slash_index = result_list[0].rfind('/')
- full_filename = result_list[0][first_slash_index+1:last_slash_index]
- total_bytes, _ = __get_data_size(full_filename)
- behavior_with_suffix = result_list[0][last_slash_index+1:]
- last_dash = behavior_with_suffix.rfind("-")
- if last_dash == -1:
- behavior = behavior_with_suffix
- else:
- behavior = behavior_with_suffix[:last_dash]
- __results.append({
- "dataFilename": __extract_file_name(full_filename),
- "throughput": total_bytes / float(result_list[2]) * 1e9 / 2 ** 20,
- "behavior": behavior,
- "language": "go"
- })
- # Self built json results example:
- #
- # [
- # {
- # "filename": string,
- # "benchmarks": {
- # behavior: results,
- # ...
- # },
- # },
- # ...
- # ]
- def __parse_custom_result(filename, language):
- if filename == "":
- return
- if filename[0] != '/':
- filename = os.path.dirname(os.path.abspath(__file__)) + '/' + filename
- with open(filename, encoding="utf-8") as f:
- results = json.loads(f.read())
- for result in results:
- _, avg_size = __get_data_size(result["filename"])
- for behavior in result["benchmarks"]:
- __results.append({
- "language": language,
- "dataFilename": __extract_file_name(result["filename"]),
- "behavior": behavior,
- "throughput": result["benchmarks"][behavior]
- })
- def __parse_js_result(filename, language):
- return __parse_custom_result(filename, language)
- def __parse_php_result(filename, language):
- return __parse_custom_result(filename, language)
- def get_result_from_file(cpp_file="",
- java_file="",
- python_file="",
- go_file="",
- synthetic_file="",
- node_file="",
- php_c_file="",
- php_file=""):
- results = {}
- if cpp_file != "":
- __parse_cpp_result(cpp_file)
- if java_file != "":
- __parse_java_result(java_file)
- if python_file != "":
- __parse_python_result(python_file)
- if go_file != "":
- __parse_go_result(go_file)
- if synthetic_file != "":
- __parse_synthetic_result(synthetic_file)
- if node_file != "":
- __parse_js_result(node_file, "node")
- if php_file != "":
- __parse_php_result(php_file, "php")
- if php_c_file != "":
- __parse_php_result(php_c_file, "php")
- return __results
- if __name__ == "__main__":
- parser = argparse.ArgumentParser()
- parser.add_argument(
- "-cpp",
- "--cpp_input_file",
- help="The CPP benchmark result file's name",
- default="")
- parser.add_argument(
- "-java",
- "--java_input_file",
- help="The Java benchmark result file's name",
- default="")
- parser.add_argument(
- "-python",
- "--python_input_file",
- help="The Python benchmark result file's name",
- default="")
- parser.add_argument(
- "-go",
- "--go_input_file",
- help="The golang benchmark result file's name",
- default="")
- parser.add_argument(
- "-node",
- "--node_input_file",
- help="The node.js benchmark result file's name",
- default="")
- parser.add_argument(
- "-php",
- "--php_input_file",
- help="The pure php benchmark result file's name",
- default="")
- parser.add_argument(
- "-php_c",
- "--php_c_input_file",
- help="The php with c ext benchmark result file's name",
- default="")
- args = parser.parse_args()
- results = get_result_from_file(
- cpp_file=args.cpp_input_file,
- java_file=args.java_input_file,
- python_file=args.python_input_file,
- go_file=args.go_input_file,
- node_file=args.node_input_file,
- php_file=args.php_input_file,
- php_c_file=args.php_c_input_file,
- )
- print(json.dumps(results, indent=2))
|