| #!/usr/bin/python |
| |
| # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Parse data from benchmark_runs for tabulator.""" |
| import re |
| |
| |
| class ResultOrganizer(object): |
| """Create a dict from benchmark_runs. |
| |
| The structure of the output dict is as follows: |
| {"benchmark_1":[ |
| [{"key1":"v1", "key2":"v2"},{"key1":"v1", "key2","v2"}] |
| #one label |
| [] |
| #the other label |
| ] |
| "benchmark_2": |
| [ |
| ]}. |
| """ |
| key_filter = ["milliseconds_", |
| "retval", |
| "iterations", |
| "ms_", |
| "score_"] |
| |
| def __init__(self, benchmark_runs, labels, benchmarks=None): |
| self.result = {} |
| self.labels = [] |
| self.prog = re.compile(r"(\w+)\{(\d+)\}") |
| self.benchmarks = benchmarks |
| if not self.benchmarks: |
| self.benchmarks = [] |
| for label in labels: |
| self.labels.append(label.name) |
| for benchmark_run in benchmark_runs: |
| benchmark_name = benchmark_run.benchmark.name |
| if benchmark_name not in self.result: |
| self.result[benchmark_name] = [] |
| while len(self.result[benchmark_name]) < len(labels): |
| self.result[benchmark_name].append([]) |
| label_index = self.labels.index(benchmark_run.label.name) |
| cur_table = self.result[benchmark_name][label_index] |
| index = benchmark_run.iteration - 1 |
| while index >= len(cur_table): |
| cur_table.append({}) |
| cur_dict = cur_table[index] |
| if not benchmark_run.result: |
| continue |
| benchmark = benchmark_run.benchmark |
| key_filter_on = (benchmark.key_results_only and |
| "PyAutoPerfTest" in benchmark.name + benchmark.test_name |
| and "perf." not in benchmark.test_args) |
| for test_key in benchmark_run.result.keyvals: |
| if (key_filter_on and |
| not any([key for key in self.key_filter if key in test_key]) |
| ): |
| continue |
| result_value = benchmark_run.result.keyvals[test_key] |
| cur_dict[test_key] = result_value |
| self._DuplicatePass() |
| |
| def _DuplicatePass(self): |
| for bench, data in self.result.items(): |
| max_dup = self._GetMaxDup(data) |
| if not max_dup: |
| continue |
| for label in data: |
| index = data.index(label) |
| data[index] = self._GetNonDupLabel(max_dup, label) |
| self._AdjustIteration(max_dup, bench) |
| |
| def _GetMaxDup(self, data): |
| """Find the maximum i inside ABCD{i}.""" |
| max_dup = 0 |
| for label in data: |
| for run in label: |
| for key in run: |
| if re.match(self.prog, key): |
| max_dup = max(max_dup, |
| int(re.search(self.prog, key).group(2))) |
| return max_dup |
| |
| def _GetNonDupLabel(self, max_dup, label): |
| """Create new list for the runs of the same label.""" |
| new_label = [] |
| for run in label: |
| start_index = len(new_label) |
| new_label.append(dict(run)) |
| for i in range(max_dup): |
| new_label.append({}) |
| new_run = new_label[start_index] |
| for key, value in new_run.items(): |
| if re.match(self.prog, key): |
| new_key = re.search(self.prog, key).group(1) |
| index = int(re.search(self.prog, key).group(2)) |
| new_label[start_index+index][new_key] = str(value) |
| del new_run[key] |
| return new_label |
| |
| def _AdjustIteration(self, max_dup, bench): |
| """Adjust the interation numbers if the have keys like ABCD{i}.""" |
| for benchmark in self.benchmarks: |
| if benchmark.name == bench: |
| if not benchmark.iteration_adjusted: |
| benchmark.iteration_adjusted = True |
| benchmark.iterations *= (max_dup +1) |