aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorRoman Lebedev <lebedev.ri@gmail.com>2021-09-03 17:36:56 +0300
committerGitHub <noreply@github.com>2021-09-03 15:36:56 +0100
commit12dc5eeafc126ec5a6c9e4efba06a171342263e9 (patch)
tree4b371291a051c5f3c4e6ce0c162b0917607e64df /tools
parent67b77da3c08f529e062ae1bfbb84a90fa36877f0 (diff)
downloadgoogle-benchmark-12dc5eeafc126ec5a6c9e4efba06a171342263e9.tar.gz
Statistics: add support for percentage unit in addition to time (#1219)
* Statistics: add support for percentage unit in addition to time I think, `stddev` statistic is useful, but confusing. What does it mean if `stddev` of `1ms` is reported? Is that good or bad? If the `median` is `1s`, then that means that the measurements are pretty noise-less. And what about `stddev` of `100ms` is reported? If the `median` is `1s` - awful, if the `median` is `10s` - good. And hurray, there is just the statistic that we need: https://en.wikipedia.org/wiki/Coefficient_of_variation But, naturally, that produces a value in percents, but the statistics are currently hardcoded to produce time. So this refactors thinkgs a bit, and allows a percentage unit for statistics. I'm not sure whether or not `benchmark` would be okay with adding this `RSD` statistic by default, but regales, that is a separate patch. Refs. https://github.com/google/benchmark/issues/1146 * Address review notes
Diffstat (limited to 'tools')
-rw-r--r--tools/gbench/Inputs/test4_run0.json21
-rw-r--r--tools/gbench/Inputs/test4_run1.json21
-rw-r--r--tools/gbench/report.py63
3 files changed, 105 insertions, 0 deletions
diff --git a/tools/gbench/Inputs/test4_run0.json b/tools/gbench/Inputs/test4_run0.json
new file mode 100644
index 0000000..54cf127
--- /dev/null
+++ b/tools/gbench/Inputs/test4_run0.json
@@ -0,0 +1,21 @@
+{
+ "context": {
+ "date": "2016-08-02 17:44:46",
+ "num_cpus": 4,
+ "mhz_per_cpu": 4228,
+ "cpu_scaling_enabled": false,
+ "library_build_type": "release"
+ },
+ "benchmarks": [
+ {
+ "name": "whocares",
+ "run_type": "aggregate",
+ "aggregate_name": "zz",
+ "aggregate_unit": "percentage",
+ "iterations": 1000,
+ "real_time": 0.01,
+ "cpu_time": 0.10,
+ "time_unit": "ns"
+ }
+ ]
+}
diff --git a/tools/gbench/Inputs/test4_run1.json b/tools/gbench/Inputs/test4_run1.json
new file mode 100644
index 0000000..25d5605
--- /dev/null
+++ b/tools/gbench/Inputs/test4_run1.json
@@ -0,0 +1,21 @@
+{
+ "context": {
+ "date": "2016-08-02 17:44:46",
+ "num_cpus": 4,
+ "mhz_per_cpu": 4228,
+ "cpu_scaling_enabled": false,
+ "library_build_type": "release"
+ },
+ "benchmarks": [
+ {
+ "name": "whocares",
+ "run_type": "aggregate",
+ "aggregate_name": "zz",
+ "aggregate_unit": "percentage",
+ "iterations": 1000,
+ "real_time": 0.005,
+ "cpu_time": 0.15,
+ "time_unit": "ns"
+ }
+ ]
+}
diff --git a/tools/gbench/report.py b/tools/gbench/report.py
index 504e15f..8203cba 100644
--- a/tools/gbench/report.py
+++ b/tools/gbench/report.py
@@ -914,6 +914,69 @@ class TestReportDifferenceWithUTestWhileDisplayingAggregatesOnly(
assert_measurements(self, out, expected)
+
+class TestReportDifferenceForPercentageAggregates(
+ unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ def load_results():
+ import json
+ testInputs = os.path.join(
+ os.path.dirname(
+ os.path.realpath(__file__)),
+ 'Inputs')
+ testOutput1 = os.path.join(testInputs, 'test4_run0.json')
+ testOutput2 = os.path.join(testInputs, 'test4_run1.json')
+ with open(testOutput1, 'r') as f:
+ json1 = json.load(f)
+ with open(testOutput2, 'r') as f:
+ json2 = json.load(f)
+ return json1, json2
+
+ json1, json2 = load_results()
+ cls.json_diff_report = get_difference_report(
+ json1, json2, utest=True)
+
+ def test_json_diff_report_pretty_printing(self):
+ expect_lines = [
+ ['whocares', '-0.5000', '+0.5000', '0', '0', '0', '0']
+ ]
+ output_lines_with_header = print_difference_report(
+ self.json_diff_report,
+ utest=True, utest_alpha=0.05, use_color=False)
+ output_lines = output_lines_with_header[2:]
+ print("\n")
+ print("\n".join(output_lines_with_header))
+ self.assertEqual(len(output_lines), len(expect_lines))
+ for i in range(0, len(output_lines)):
+ parts = [x for x in output_lines[i].split(' ') if x]
+ self.assertEqual(expect_lines[i], parts)
+
+ def test_json_diff_report(self):
+ expected_output = [
+ {
+ 'name': u'whocares',
+ 'measurements': [
+ {'time': -0.5,
+ 'cpu': 0.5,
+ 'real_time': 0.01,
+ 'real_time_other': 0.005,
+ 'cpu_time': 0.10,
+ 'cpu_time_other': 0.15}
+ ],
+ 'time_unit': 'ns',
+ 'utest': {}
+ }
+ ]
+ self.assertEqual(len(self.json_diff_report), len(expected_output))
+ for out, expected in zip(
+ self.json_diff_report, expected_output):
+ self.assertEqual(out['name'], expected['name'])
+ self.assertEqual(out['time_unit'], expected['time_unit'])
+ assert_utest(self, out, expected)
+ assert_measurements(self, out, expected)
+
+
class TestReportSorting(unittest.TestCase):
@classmethod
def setUpClass(cls):