Page MenuHomeClusterLabs Projects

pcmk_simtimes.in
No OneTemporary

pcmk_simtimes.in

#!@PYTHON@
""" Timing comparisons for crm_simulate profiling output
"""
__copyright__ = "Copyright 2019-2023 the Pacemaker project contributors"
__license__ = "GNU General Public License version 2 or later (GPLv2+) WITHOUT ANY WARRANTY"
import io
import re
import sys
import errno
import argparse
import os
# These imports allow running from a source checkout after running `make`.
# Note that while this doesn't necessarily mean it will successfully run tests,
# but being able to see --help output can be useful.
if os.path.exists("@abs_top_srcdir@/python"):
sys.path.insert(0, "@abs_top_srcdir@/python")
if os.path.exists("@abs_top_builddir@/python") and "@abs_top_builddir@" != "@abs_top_srcdir@":
sys.path.insert(0, "@abs_top_builddir@/python")
from pacemaker.exitstatus import ExitStatus
DESC = """Compare timings from crm_simulate profiling output"""
BEFORE_HELP = """Output of "crm_simulate --profile cts/scheduler --repeat <N>" from earlier Pacemaker build"""
# line like: * Testing cts/scheduler/xml/1360.xml ... 0.07 secs
PATTERN = r"""^\s*\*\s+Testing\s+.*/([^/]+)\.xml\s+\.+\s+([.0-9]+)\s+secs\s*$"""
def parse_args(argv=sys.argv):
""" Parse command-line arguments """
parser = argparse.ArgumentParser(description=DESC)
parser.add_argument('-V', '--verbose', action='count',
help='Increase verbosity')
parser.add_argument('-p', '--threshold-percent', type=float, default=0,
help="Don't show tests with less than this percentage difference in times")
parser.add_argument('-s', '--threshold-seconds', type=float, default=0,
help="Don't show tests with less than this seconds difference in times")
parser.add_argument('-S', '--sort', choices=['test', 'before', 'after', 'diff', 'percent'],
default='test', help="Sort results by this column")
parser.add_argument('-r', '--reverse', action='store_true',
help="Sort results in descending order")
parser.add_argument('before_file', metavar='BEFORE',
type=argparse.FileType('r'),
help=BEFORE_HELP)
parser.add_argument('after_file', metavar='AFTER',
type=argparse.FileType('r'),
help='Output of same command from later Pacemaker build')
return parser.parse_args(argv[1:])
def extract_times(infile):
""" Extract test names and times into hash table from file """
result = {}
for line in infile:
match = re.search(PATTERN, line)
if match is not None:
result[match.group(1)] = match.group(2)
return result
def compare_test(test, before, after, args):
""" Compare one test's timings """
try:
before_time = float(before[test])
except KeyError:
if args.verbose > 0:
print("No previous test " + test + " to compare")
return None
after_time = float(after[test])
time_diff = after_time - before_time
time_diff_percent = (time_diff / before_time) * 100
if ((abs(time_diff) >= args.threshold_seconds)
and (abs(time_diff_percent) >= args.threshold_percent)):
return { 'test': test,
'before': before_time,
'after': after_time,
'diff': time_diff,
'percent': time_diff_percent
}
return None
def sort_diff(result):
""" Sort two test results by time difference """
global sort_field
return result[sort_field]
def print_results(results, sort_reverse):
""" Output the comparison results """
if results == []:
return
# Sort and print test differences
results.sort(reverse=sort_reverse, key=sort_diff)
for result in results:
print("%-40s %6.2fs vs %6.2fs (%+.2fs = %+6.2f%%)" % (result['test'],
result['before'], result['after'], result['diff'],
result['percent']))
# Print average differences
diff_total = sum(d['diff'] for d in results)
percent_total = sum(d['percent'] for d in results)
nresults = len(results)
print("\nAverages: %+.2fs %+6.2f%%" % ((diff_total / nresults),
(percent_total / nresults)))
if __name__ == "__main__":
global sort_field
try:
args = parse_args()
if args.verbose is None:
args.verbose = 0
before = extract_times(args.before_file)
after = extract_times(args.after_file)
sort_field = args.sort
# Build a list of test differences
results = []
for test in after.keys():
result = compare_test(test, before, after, args)
if result is not None:
results = results + [ result ]
print_results(results, sort_reverse=args.reverse)
except KeyboardInterrupt:
pass
except IOError as e:
if e.errno != errno.EPIPE:
raise
sys.exit(ExitStatus.OK)
# vim: set filetype=python expandtab tabstop=4 softtabstop=4 shiftwidth=4 textwidth=120:

File Metadata

Mime Type
text/x-script.python
Expires
Mon, Dec 23, 12:36 PM (1 d, 13 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1120026
Default Alt Text
pcmk_simtimes.in (4 KB)

Event Timeline