You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
233 lines
9.9 KiB
233 lines
9.9 KiB
#!/usr/bin/python2 |
|
# |
|
# Copyright 2016 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. |
|
"""Runs an experiment with the benchmark metrics on a pair of CWP data sets. |
|
|
|
A data set should contain the files with the pairwise inclusive and the |
|
inclusive statistics. The pairwise inclusive file contains pairs of |
|
parent and child functions with their inclusive count fractions out of the |
|
total amount of inclusive count values and the files of the child functions. |
|
The inclusive file contains the functions with their inclusive count fraction |
|
out of the total amount of inclusive count values and the file name of the |
|
function. The input data should be collected using the scripts |
|
collect_experiment_data.sh or collect_experiment_data_odd_even_session.sh |
|
|
|
For every function, this script computes the distance and the score values. |
|
The output is stored in the file cwp_functions_statistics_file. |
|
|
|
For every Chrome OS component, this script computes a set of metrics consisting |
|
in the number of functions, the average and cumulative distance and score of |
|
the functions matching the group. The output is stored in the file |
|
cwp_function_groups_statistics_file. |
|
""" |
|
|
|
import argparse |
|
import sys |
|
|
|
import benchmark_metrics |
|
import utils |
|
|
|
|
|
class MetricsExperiment(object): |
|
"""Runs an experiment with the benchmark metrics on a pair of data sets.""" |
|
|
|
def __init__(self, cwp_pairwise_inclusive_reference, |
|
cwp_pairwise_inclusive_test, cwp_inclusive_reference, |
|
cwp_inclusive_test, cwp_function_groups_file, |
|
cwp_function_groups_statistics_file, |
|
cwp_function_statistics_file): |
|
"""Initializes the MetricsExperiment class. |
|
|
|
Args: |
|
cwp_pairwise_inclusive_reference: The CSV file containing the pairwise |
|
inclusive values from the reference data set. |
|
cwp_pairwise_inclusive_test: The CSV file containing the pairwise |
|
inclusive values from the test data set. |
|
cwp_inclusive_reference: The CSV file containing the inclusive values |
|
from the reference data set. |
|
cwp_inclusive_test: The CSV file containing the inclusive values from |
|
the test data set. |
|
cwp_function_groups_file: The CSV file containing the groups of functions. |
|
cwp_function_groups_statistics_file: The output CSV file that will |
|
contain the metrics for the function groups. |
|
cwp_function_statistics_file: The output CSV file that will contain the |
|
metrics for the CWP functions. |
|
""" |
|
self._cwp_pairwise_inclusive_reference = cwp_pairwise_inclusive_reference |
|
self._cwp_pairwise_inclusive_test = cwp_pairwise_inclusive_test |
|
self._cwp_inclusive_reference = cwp_inclusive_reference |
|
self._cwp_inclusive_test = cwp_inclusive_test |
|
self._cwp_function_groups_file = cwp_function_groups_file |
|
self._cwp_function_groups_statistics_file = \ |
|
cwp_function_groups_statistics_file |
|
self._cwp_function_statistics_file = cwp_function_statistics_file |
|
|
|
def PerformComputation(self): |
|
"""Does the benchmark metrics experimental computation. |
|
|
|
For every function, it is computed a distance based on the sum of the |
|
differences of the fractions spent in the child functions. Afterwards, |
|
it is computed a score based on the inclusive values fractions and the |
|
distance value. The statistics for all the function are written in the file |
|
self._cwp_function_statistics_file. |
|
|
|
The functions are grouped on Chrome OS components based on the path of the |
|
file where a function is defined. For every group, there are computed the |
|
total number of functions matching that group, the cumulative distance, the |
|
average distance and the cumulative score of the functions. |
|
""" |
|
|
|
inclusive_statistics_reference = \ |
|
utils.ParseCWPInclusiveCountFile(self._cwp_inclusive_reference) |
|
inclusive_statistics_cum_reference = \ |
|
utils.ComputeCWPCummulativeInclusiveStatistics( |
|
inclusive_statistics_reference) |
|
inclusive_statistics_test = \ |
|
utils.ParseCWPInclusiveCountFile(self._cwp_inclusive_test) |
|
inclusive_statistics_cum_test = \ |
|
utils.ComputeCWPCummulativeInclusiveStatistics( |
|
inclusive_statistics_test) |
|
pairwise_inclusive_statistics_reference = \ |
|
utils.ParseCWPPairwiseInclusiveCountFile( |
|
self._cwp_pairwise_inclusive_reference) |
|
pairwise_inclusive_fractions_reference = \ |
|
utils.ComputeCWPChildFunctionsFractions( |
|
inclusive_statistics_cum_reference, |
|
pairwise_inclusive_statistics_reference) |
|
pairwise_inclusive_statistics_test = \ |
|
utils.ParseCWPPairwiseInclusiveCountFile( |
|
self._cwp_pairwise_inclusive_test) |
|
pairwise_inclusive_fractions_test = \ |
|
utils.ComputeCWPChildFunctionsFractions( |
|
inclusive_statistics_cum_test, |
|
pairwise_inclusive_statistics_test) |
|
parent_function_statistics = {} |
|
|
|
with open(self._cwp_function_groups_file) as input_file: |
|
cwp_function_groups = utils.ParseFunctionGroups(input_file.readlines()) |
|
|
|
for parent_function_key, parent_function_statistics_test \ |
|
in inclusive_statistics_test.iteritems(): |
|
parent_function_name, _ = parent_function_key.split(',') |
|
parent_function_fraction_test = parent_function_statistics_test[2] |
|
|
|
parent_function_fraction_reference = \ |
|
inclusive_statistics_reference[parent_function_key][2] |
|
|
|
child_functions_fractions_test = \ |
|
pairwise_inclusive_fractions_test.get(parent_function_name, {}) |
|
|
|
child_functions_fractions_reference = \ |
|
pairwise_inclusive_fractions_reference.get(parent_function_name, {}) |
|
|
|
distance = benchmark_metrics.ComputeDistanceForFunction( |
|
child_functions_fractions_test, child_functions_fractions_reference) |
|
|
|
parent_function_score_test = benchmark_metrics.ComputeScoreForFunction( |
|
distance, parent_function_fraction_test, |
|
parent_function_fraction_reference) |
|
|
|
parent_function_statistics[parent_function_key] = \ |
|
(distance, parent_function_score_test) |
|
|
|
with open(self._cwp_function_statistics_file, 'w') as output_file: |
|
statistics_lines = ['function,file,distance,score'] |
|
statistics_lines += \ |
|
[','.join([parent_function_key.replace(';;', ','), |
|
str(statistic[0]), |
|
str(statistic[1])]) |
|
for parent_function_key, statistic |
|
in parent_function_statistics.iteritems()] |
|
output_file.write('\n'.join(statistics_lines)) |
|
|
|
cwp_groups_statistics_test = benchmark_metrics.ComputeMetricsForComponents( |
|
cwp_function_groups, parent_function_statistics) |
|
|
|
with open(self._cwp_function_groups_statistics_file, 'w') as output_file: |
|
group_statistics_lines = \ |
|
['group,file_path,function_count,distance_cum,distance_avg,score_cum,' |
|
'score_avg'] |
|
group_statistics_lines += \ |
|
[','.join([group_name, |
|
str(statistic[0]), |
|
str(statistic[1]), |
|
str(statistic[2]), |
|
str(statistic[3]), |
|
str(statistic[4]), |
|
str(statistic[5])]) |
|
for group_name, statistic |
|
in cwp_groups_statistics_test.iteritems()] |
|
output_file.write('\n'.join(group_statistics_lines)) |
|
|
|
|
|
def ParseArguments(arguments): |
|
parser = argparse.ArgumentParser( |
|
description='Runs an experiment with the benchmark metrics on a pair of ' |
|
'CWP data sets.') |
|
parser.add_argument( |
|
'--cwp_pairwise_inclusive_reference', |
|
required=True, |
|
help='The reference CSV file that will contain a pair of parent and ' |
|
'child functions with their inclusive count fractions out of the total ' |
|
'amount of inclusive count values.') |
|
parser.add_argument( |
|
'--cwp_pairwise_inclusive_test', |
|
required=True, |
|
help='The test CSV file that will contain a pair of parent and ' |
|
'child functions with their inclusive count fractions out of the total ' |
|
'amount of inclusive count values.') |
|
parser.add_argument( |
|
'--cwp_inclusive_reference', |
|
required=True, |
|
help='The reference CSV file that will contain a function with its ' |
|
'inclusive count fraction out of the total amount of inclusive count ' |
|
'values.') |
|
parser.add_argument( |
|
'--cwp_inclusive_test', |
|
required=True, |
|
help='The test CSV file that will contain a function with its ' |
|
'inclusive count fraction out of the total amount of inclusive count ' |
|
'values.') |
|
parser.add_argument( |
|
'-g', |
|
'--cwp_function_groups_file', |
|
required=True, |
|
help='The file that will contain the CWP function groups.' |
|
'A line consists in the group name and a file path. A group must ' |
|
'represent a ChromeOS component.') |
|
parser.add_argument( |
|
'-s', |
|
'--cwp_function_groups_statistics_file', |
|
required=True, |
|
help='The output file that will contain the metric statistics for the ' |
|
'CWP function groups in CSV format. A line consists in the group name, ' |
|
'file path, number of functions matching the group, the total score ' |
|
'and distance values.') |
|
parser.add_argument( |
|
'-f', |
|
'--cwp_function_statistics_file', |
|
required=True, |
|
help='The output file that will contain the metric statistics for the ' |
|
'CWP functions in CSV format. A line consists in the function name, file ' |
|
'name, cummulative distance, average distance, cummulative score and ' |
|
'average score values.') |
|
|
|
options = parser.parse_args(arguments) |
|
return options |
|
|
|
|
|
def Main(argv): |
|
options = ParseArguments(argv) |
|
metrics_experiment = MetricsExperiment( |
|
options.cwp_pairwise_inclusive_reference, |
|
options.cwp_pairwise_inclusive_test, options.cwp_inclusive_reference, |
|
options.cwp_inclusive_test, options.cwp_function_groups_file, |
|
options.cwp_function_groups_statistics_file, |
|
options.cwp_function_statistics_file) |
|
metrics_experiment.PerformComputation() |
|
|
|
|
|
if __name__ == '__main__': |
|
Main(sys.argv[1:])
|
|
|