bench.py (4241B)
1 #!/usr/bin/env python3 2 3 # Copyright 2022 ByteDance Inc. 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 import tempfile 18 import os 19 import subprocess 20 import argparse 21 22 gbench_prefix = "SONIC_NO_ASYNC_GC=1 go test -benchmem -run=none " 23 24 def run(cmd): 25 print(cmd) 26 if os.system(cmd): 27 print ("Failed to run cmd: %s"%(cmd)) 28 exit(1) 29 30 def run_s(cmd): 31 print (cmd) 32 try: 33 res = os.popen(cmd) 34 except subprocess.CalledProcessError as e: 35 if e.returncode: 36 print (e.output) 37 exit(1) 38 return res.read() 39 40 def run_r(cmd): 41 print (cmd) 42 try: 43 cmds = cmd.split(' ') 44 data = subprocess.check_output(cmds, stderr=subprocess.STDOUT) 45 except subprocess.CalledProcessError as e: 46 if e.returncode: 47 print (e.output) 48 exit(1) 49 return data.decode("utf-8") 50 51 def compare(args): 52 # detech current branch. 53 # result = run_r("git branch") 54 current_branch = run_s("git status | head -n1 | sed 's/On branch //'") 55 # for br in result.split('\n'): 56 # if br.startswith("* "): 57 # current_branch = br.lstrip('* ') 58 # break 59 60 if not current_branch: 61 print ("Failed to detech current branch") 62 return None 63 64 # get the current diff 65 (fd, diff) = tempfile.mkstemp() 66 run("git diff > %s"%diff) 67 68 # early return if currrent is main branch. 69 print ("Current branch: %s"%(current_branch)) 70 if current_branch == "main": 71 print ("Cannot compare at the main branch.Please build a new branch") 72 return None 73 74 # benchmark current branch 75 (fd, target) = tempfile.mkstemp(".target.txt") 76 run("%s %s ./... 2>&1 | tee %s" %(gbench_prefix, args, target)) 77 78 # trying to switch to the latest main branch 79 run("git checkout -- .") 80 if current_branch != "main": 81 run("git checkout main") 82 run("git pull --allow-unrelated-histories origin main") 83 84 # benchmark main branch 85 (fd, main) = tempfile.mkstemp(".main.txt") 86 run("%s %s ./... 2>&1 | tee %s" %(gbench_prefix, args, main)) 87 88 # diff the result 89 # benchstat = "go get golang.org/x/perf/cmd/benchstat && go install golang.org/x/perf/cmd/benchstat" 90 run( "benchstat -sort=delta %s %s"%(main, target)) 91 run("git checkout -- .") 92 93 # restore branch 94 if current_branch != "main": 95 run("git checkout %s"%(current_branch)) 96 run("patch -p1 < %s" % (diff)) 97 return target 98 99 def main(): 100 argparser = argparse.ArgumentParser(description='Tools to test the performance. Example: ./bench.py -b Decoder_Generic_Sonic -c') 101 argparser.add_argument('-b', '--bench', dest='filter', required=False, 102 help='Specify the filter for golang benchmark') 103 argparser.add_argument('-c', '--compare', dest='compare', action='store_true', required=False, 104 help='Compare with the main benchmarking') 105 argparser.add_argument('-t', '--times', dest='times', required=False, 106 help='benchmark the times') 107 argparser.add_argument('-r', '--repeat_times', dest='count', required=False, 108 help='benchmark the count') 109 args = argparser.parse_args() 110 111 if args.filter: 112 gbench_args = "-bench=%s"%(args.filter) 113 else: 114 gbench_args = "-bench=." 115 116 if args.times: 117 gbench_args += " -benchtime=%s"%(args.times) 118 119 if args.count: 120 gbench_args += " -count=%s"%(args.count) 121 else: 122 gbench_args += " -count=10" 123 124 if args.compare: 125 target = compare(gbench_args) 126 else: 127 target = None 128 129 if not target: 130 (fd, target) = tempfile.mkstemp(".target.txt") 131 run("%s %s ./... 2>&1 | tee %s" %(gbench_prefix, gbench_args, target)) 132 133 if __name__ == "__main__": 134 main()