| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Performance Test Bisect Tool | 6 """Performance Test Bisect Tool |
| 7 | 7 |
| 8 This script bisects a series of changelists using binary search. It starts at | 8 This script bisects a series of changelists using binary search. It starts at |
| 9 a bad revision where a performance metric has regressed, and asks for a last | 9 a bad revision where a performance metric has regressed, and asks for a last |
| 10 known-good revision. It will then binary search across this revision range by | 10 known-good revision. It will then binary search across this revision range by |
| (...skipping 1927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1938 """Attempts to parse a metric in the format RESULT <graph>: <trace>= ... | 1938 """Attempts to parse a metric in the format RESULT <graph>: <trace>= ... |
| 1939 | 1939 |
| 1940 Args: | 1940 Args: |
| 1941 metric: The metric as a list of [<trace>, <value>] strings. | 1941 metric: The metric as a list of [<trace>, <value>] strings. |
| 1942 text: The text to parse the metric values from. | 1942 text: The text to parse the metric values from. |
| 1943 | 1943 |
| 1944 Returns: | 1944 Returns: |
| 1945 A list of floating point numbers found. | 1945 A list of floating point numbers found. |
| 1946 """ | 1946 """ |
| 1947 # Format is: RESULT <graph>: <trace>= <value> <units> | 1947 # Format is: RESULT <graph>: <trace>= <value> <units> |
| 1948 metric_formatted = re.escape('RESULT %s: %s=' % (metric[0], metric[1])) | 1948 metric_re = re.escape('RESULT %s: %s=' % (metric[0], metric[1])) |
| 1949 |
| 1950 # The log will be parsed looking for format: |
| 1951 # <*>RESULT <graph_name>: <trace_name>= <value> |
| 1952 single_result_re = re.compile( |
| 1953 metric_re + '\s*(?P<VALUE>[-]?\d*(\.\d*)?)') |
| 1954 |
| 1955 # The log will be parsed looking for format: |
| 1956 # <*>RESULT <graph_name>: <trace_name>= [<value>,value,value,...] |
| 1957 multi_results_re = re.compile( |
| 1958 metric_re + '\s*\[\s*(?P<VALUES>[-]?[\d\., ]+)\s*\]') |
| 1959 |
| 1960 # The log will be parsed looking for format: |
| 1961 # <*>RESULT <graph_name>: <trace_name>= {<mean>, <std deviation>} |
| 1962 mean_stddev_re = re.compile( |
| 1963 metric_re + |
| 1964 '\s*\{\s*(?P<MEAN>[-]?\d*(\.\d*)?),\s*(?P<STDDEV>\d+(\.\d*)?)\s*\}') |
| 1949 | 1965 |
| 1950 text_lines = text.split('\n') | 1966 text_lines = text.split('\n') |
| 1951 values_list = [] | 1967 values_list = [] |
| 1952 | |
| 1953 for current_line in text_lines: | 1968 for current_line in text_lines: |
| 1954 # Parse the output from the performance test for the metric we're | 1969 # Parse the output from the performance test for the metric we're |
| 1955 # interested in. | 1970 # interested in. |
| 1956 metric_re = metric_formatted +\ | 1971 single_result_match = single_result_re.search(current_line) |
| 1957 "(\s)*(?P<values>[0-9]+(\.[0-9]*)?)" | 1972 multi_results_match = multi_results_re.search(current_line) |
| 1958 metric_re = re.compile(metric_re) | 1973 mean_stddev_match = mean_stddev_re.search(current_line) |
| 1959 regex_results = metric_re.search(current_line) | 1974 if (not single_result_match is None and |
| 1960 | 1975 single_result_match.group('VALUE')): |
| 1961 if not regex_results is None: | 1976 values_list += [single_result_match.group('VALUE')] |
| 1962 values_list += [regex_results.group('values')] | 1977 elif (not multi_results_match is None and |
| 1963 else: | 1978 multi_results_match.group('VALUES')): |
| 1964 metric_re = metric_formatted +\ | 1979 metric_values = multi_results_match.group('VALUES') |
| 1965 "(\s)*\[(\s)*(?P<values>[0-9,.]+)\]" | 1980 values_list += metric_values.split(',') |
| 1966 metric_re = re.compile(metric_re) | 1981 elif (not mean_stddev_match is None and |
| 1967 regex_results = metric_re.search(current_line) | 1982 mean_stddev_match.group('MEAN')): |
| 1968 | 1983 values_list += [mean_stddev_match.group('MEAN')] |
| 1969 if not regex_results is None: | |
| 1970 metric_values = regex_results.group('values') | |
| 1971 | |
| 1972 values_list += metric_values.split(',') | |
| 1973 | 1984 |
| 1974 values_list = [float(v) for v in values_list if IsStringFloat(v)] | 1985 values_list = [float(v) for v in values_list if IsStringFloat(v)] |
| 1975 | 1986 |
| 1976 # If the metric is times/t, we need to sum the timings in order to get | 1987 # If the metric is times/t, we need to sum the timings in order to get |
| 1977 # similar regression results as the try-bots. | 1988 # similar regression results as the try-bots. |
| 1978 metrics_to_sum = [['times', 't'], ['times', 'page_load_time'], | 1989 metrics_to_sum = [['times', 't'], ['times', 'page_load_time'], |
| 1979 ['cold_times', 'page_load_time'], ['warm_times', 'page_load_time']] | 1990 ['cold_times', 'page_load_time'], ['warm_times', 'page_load_time']] |
| 1980 | 1991 |
| 1981 if metric in metrics_to_sum: | 1992 if metric in metrics_to_sum: |
| 1982 if values_list: | 1993 if values_list: |
| (...skipping 1910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3893 # The perf dashboard scrapes the "results" step in order to comment on | 3904 # The perf dashboard scrapes the "results" step in order to comment on |
| 3894 # bugs. If you change this, please update the perf dashboard as well. | 3905 # bugs. If you change this, please update the perf dashboard as well. |
| 3895 bisect_utils.OutputAnnotationStepStart('Results') | 3906 bisect_utils.OutputAnnotationStepStart('Results') |
| 3896 print 'Error: %s' % e.message | 3907 print 'Error: %s' % e.message |
| 3897 if opts.output_buildbot_annotations: | 3908 if opts.output_buildbot_annotations: |
| 3898 bisect_utils.OutputAnnotationStepClosed() | 3909 bisect_utils.OutputAnnotationStepClosed() |
| 3899 return 1 | 3910 return 1 |
| 3900 | 3911 |
| 3901 if __name__ == '__main__': | 3912 if __name__ == '__main__': |
| 3902 sys.exit(main()) | 3913 sys.exit(main()) |
| OLD | NEW |