benchmark_metrics.py revision 77abf01f2cff8bb3a5564f554d9218c085b83d65
1# Copyright 2016 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4"""Computes the metrics for functions, Chrome OS components and benchmarks.""" 5 6import collections 7 8 9def ComputeDistanceForFunction(child_functions_statistics_sample, 10 child_functions_statistics_reference): 11 """Computes the distance metric for a function. 12 13 Args: 14 child_functions_statistics_sample: A dict that has as a key the name of a 15 function and as a value the inclusive count fraction. The keys are 16 the child functions of a sample parent function. 17 child_functions_statistics_reference: A dict that has as a key the name of 18 a function and as a value the inclusive count fraction. The keys are 19 the child functions of a reference parent function. 20 Returns: 21 A float value representing the sum of inclusive count fraction 22 differences of pairs of common child functions. If a child function is 23 present in a single data set, then we consider the missing inclusive 24 count fraction as 0. This value describes the difference in behaviour 25 between a sample and the reference parent function. 26 """ 27 # We initialize the distance with a small value to avoid the further 28 # division by zero. 29 distance = 1.0 30 31 for child_function, inclusive_count_fraction_reference in \ 32 child_functions_statistics_reference.iteritems(): 33 inclusive_count_fraction_sample = 0.0 34 35 if child_function in child_functions_statistics_sample: 36 inclusive_count_fraction_sample = \ 37 child_functions_statistics_sample[child_function] 38 distance += \ 39 abs(inclusive_count_fraction_sample - 40 inclusive_count_fraction_reference) 41 42 for child_function, inclusive_count_fraction_sample in \ 43 child_functions_statistics_sample.iteritems(): 44 if child_function not in child_functions_statistics_reference: 45 distance += inclusive_count_fraction_sample 46 47 return distance 48 49 50def ComputeScoreForFunction(distance, reference_fraction, sample_fraction): 51 """Computes the score for a function. 52 53 Args: 54 distance: A float value representing the difference in behaviour between 55 the sample and the reference function. 56 reference_fraction: A float value representing the inclusive count 57 fraction of the reference function. 58 sample_fraction: A float value representing the inclusive count 59 fraction of the sample function. 60 Returns: 61 A float value representing the score of the function. 62 """ 63 return reference_fraction * sample_fraction / distance 64 65 66def ComputeMetricsForComponents(cwp_function_groups, function_metrics): 67 """Computes the metrics for a set of Chrome OS components. 68 69 For every Chrome OS group, we compute the number of functions matching the 70 group, the cumulative and average score, the cumulative and average distance 71 of all those functions. A function matches a group if the path of the file 72 containing its definition contains the common path describing the group. 73 74 Args: 75 cwp_function_groups: A dict having as a key the name of the group and as a 76 value a common path describing the group. 77 function_metrics: A dict having as a key the name of the function and the 78 name of the file where it is declared concatenated by a ',', and as a 79 value a tuple containing the distance and the score metrics. 80 Returns: 81 A dict containing as a key the name of the group and as a value a tuple 82 with the group file path, the number of functions matching the group, 83 the cumulative and average score, cumulative and average distance of all 84 those functions. 85 """ 86 function_groups_metrics = \ 87 collections.defaultdict(lambda : (0, 0.0, 0.0, 0.0, 0.0)) 88 89 for function_key, metric in function_metrics.iteritems(): 90 function, function_file = function_key.split(',') 91 92 for group, common_path in cwp_function_groups: 93 if common_path not in function_file: 94 continue 95 96 function_distance = metric[0] 97 function_score = metric[1] 98 group_statistic = function_groups_metrics[group] 99 100 function_count = group_statistic[1] + 1 101 function_distance_cum = function_distance + group_statistic[2] 102 function_distance_avg = function_distance_cum / float(function_count) 103 function_score_cum = function_score + group_statistic[4] 104 function_score_avg = function_score_cum / float(function_count) 105 106 function_groups_metrics[group] = \ 107 (common_path, 108 function_count, 109 function_distance_cum, 110 function_distance_avg, 111 function_score_cum, 112 function_score_avg) 113 break 114 115 return function_groups_metrics 116 117 118def ComputeMetricsForBenchmark(function_metrics): 119 function_count = len(function_metrics.keys()) 120 distance_cum = 0.0 121 distance_avg = 0.0 122 score_cum = 0.0 123 score_avg = 0.0 124 125 for distance, score in function_metrics.values(): 126 distance_cum += distance 127 score_cum += score 128 129 distance_avg = distance_cum / float(function_count) 130 score_avg = score_cum / float(function_count) 131 return function_count, distance_cum, distance_avg, score_cum, score_avg 132 133 134def ComputeMetricsForBenchmarkSet(benchmark_set_function_metrics, 135 cwp_function_groups): 136 """TODO(evelinad): Add the computation of the metrics for a set of benchmarks. 137 """ 138 raise NotImplementedError() 139