| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright 2015 the V8 project authors. All rights reserved. | 3 # Copyright 2015 the V8 project authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 """This script is used to analyze GCTracer's NVP output.""" | 7 """This script is used to analyze GCTracer's NVP output.""" |
| 8 | 8 |
| 9 |
| 9 from argparse import ArgumentParser | 10 from argparse import ArgumentParser |
| 11 from copy import deepcopy |
| 10 from gc_nvp_common import split_nvp | 12 from gc_nvp_common import split_nvp |
| 11 from sys import stdin | 13 from sys import stdin |
| 12 | 14 |
| 15 |
| 13 class Histogram: | 16 class Histogram: |
| 14 def __init__(self, values, granularity): | 17 def __init__(self, granularity, fill_empty): |
| 15 self.values = list(values) # copy over values | |
| 16 self.granularity = granularity | 18 self.granularity = granularity |
| 19 self.histogram = {} |
| 20 self.fill_empty = fill_empty |
| 21 |
| 22 def add(self, key): |
| 23 index = int(key / self.granularity) |
| 24 if index not in self.histogram: |
| 25 self.histogram[index] = 0 |
| 26 self.histogram[index] += 1 |
| 17 | 27 |
| 18 def __str__(self): | 28 def __str__(self): |
| 19 ret = [] | 29 ret = [] |
| 20 values = list(self.values) # copy over values | 30 keys = self.histogram.keys() |
| 21 min_value = 0 | 31 keys.sort() |
| 22 while len(values) > 0: | 32 last = -self.granularity |
| 23 max_value = min_value + self.granularity | 33 for key in keys: |
| 24 sub = [x for x in self.values if x >= min_value and x < max_value] | 34 min_value = key * self.granularity |
| 35 max_value = min_value + self.granularity |
| 36 |
| 37 if self.fill_empty: |
| 38 while (last + self.granularity) != min_value: |
| 39 last += self.granularity |
| 40 ret.append(" [{0},{1}[: {2}".format( |
| 41 str(last), str(last + self.granularity), 0)) |
| 42 |
| 25 ret.append(" [{0},{1}[: {2}".format( | 43 ret.append(" [{0},{1}[: {2}".format( |
| 26 str(min_value), str(max_value),len(sub))) | 44 str(min_value), str(max_value), self.histogram[key])) |
| 27 min_value += self.granularity | 45 last = min_value |
| 28 values = [x for x in values if x not in sub] | |
| 29 return "\n".join(ret) | 46 return "\n".join(ret) |
| 30 | 47 |
| 31 | 48 |
| 32 class Category: | 49 class Category: |
| 33 def __init__(self, key, histogram, granularity): | 50 def __init__(self, key, histogram): |
| 34 self.key = key | 51 self.key = key |
| 35 self.values = [] | 52 self.values = [] |
| 36 self.histogram = histogram | 53 self.histogram = histogram |
| 37 self.granularity = granularity | |
| 38 | 54 |
| 39 def process_entry(self, entry): | 55 def process_entry(self, entry): |
| 40 if self.key in entry: | 56 if self.key in entry: |
| 41 self.values.append(float(entry[self.key])) | 57 self.values.append(float(entry[self.key])) |
| 58 if self.histogram: |
| 59 self.histogram.add(float(entry[self.key])) |
| 42 | 60 |
| 43 def __str__(self): | 61 def __str__(self): |
| 44 ret = [self.key] | 62 ret = [self.key] |
| 45 ret.append(" len: {0}".format(len(self.values))) | 63 ret.append(" len: {0}".format(len(self.values))) |
| 46 if len(self.values) > 0: | 64 if len(self.values) > 0: |
| 47 ret.append(" min: {0}".format(min(self.values))) | 65 ret.append(" min: {0}".format(min(self.values))) |
| 48 ret.append(" max: {0}".format(max(self.values))) | 66 ret.append(" max: {0}".format(max(self.values))) |
| 49 ret.append(" avg: {0}".format(sum(self.values) / len(self.values))) | 67 ret.append(" avg: {0}".format(sum(self.values) / len(self.values))) |
| 50 if self.histogram: | 68 if self.histogram: |
| 51 ret.append(str(Histogram(self.values, self.granularity))) | 69 ret.append(str(self.histogram)) |
| 52 return "\n".join(ret) | 70 return "\n".join(ret) |
| 53 | 71 |
| 54 | 72 |
| 55 def main(): | 73 def main(): |
| 56 parser = ArgumentParser(description="Process GCTracer's NVP output") | 74 parser = ArgumentParser(description="Process GCTracer's NVP output") |
| 57 parser.add_argument('keys', metavar='KEY', type=str, nargs='+', | 75 parser.add_argument('keys', metavar='KEY', type=str, nargs='+', |
| 58 help='the keys (names) to process') | 76 help='the keys (names) to process') |
| 59 parser.add_argument('--histogram-granularity', metavar='GRANULARITY', | 77 parser.add_argument('--histogram-granularity', metavar='GRANULARITY', |
| 60 type=int, nargs='?', default=5, | 78 type=int, nargs='?', default=5, |
| 61 help='histogram granularity (default: 5)') | 79 help='histogram granularity (default: 5)') |
| 80 parser.add_argument('--no-histogram-print-empty', dest='histogram_print_empty'
, |
| 81 action='store_false', |
| 82 help='print empty histogram buckets') |
| 62 feature_parser = parser.add_mutually_exclusive_group(required=False) | 83 feature_parser = parser.add_mutually_exclusive_group(required=False) |
| 63 feature_parser.add_argument('--histogram', dest='histogram', | 84 feature_parser.add_argument('--histogram', dest='histogram', |
| 64 action='store_true', | 85 action='store_true', |
| 65 help='print histogram') | 86 help='print histogram') |
| 66 feature_parser.add_argument('--no-histogram', dest='histogram', | 87 feature_parser.add_argument('--no-histogram', dest='histogram', |
| 67 action='store_false', | 88 action='store_false', |
| 68 help='do not print histogram') | 89 help='do not print histogram') |
| 69 parser.set_defaults(histogram=True) | 90 parser.set_defaults(histogram=True) |
| 91 parser.set_defaults(histogram_print_empty=True) |
| 70 args = parser.parse_args() | 92 args = parser.parse_args() |
| 71 | 93 |
| 72 categories = [ Category(key, args.histogram, args.histogram_granularity) | 94 histogram = None |
| 95 if args.histogram: |
| 96 histogram = Histogram(args.histogram_granularity, args.histogram_print_empty
) |
| 97 |
| 98 categories = [ Category(key, deepcopy(histogram)) |
| 73 for key in args.keys ] | 99 for key in args.keys ] |
| 74 | 100 |
| 75 while True: | 101 while True: |
| 76 line = stdin.readline() | 102 line = stdin.readline() |
| 77 if not line: | 103 if not line: |
| 78 break | 104 break |
| 79 obj = split_nvp(line) | 105 obj = split_nvp(line) |
| 80 for category in categories: | 106 for category in categories: |
| 81 category.process_entry(obj) | 107 category.process_entry(obj) |
| 82 | 108 |
| 83 for category in categories: | 109 for category in categories: |
| 84 print(category) | 110 print(category) |
| 85 | 111 |
| 86 | 112 |
| 87 if __name__ == '__main__': | 113 if __name__ == '__main__': |
| 88 main() | 114 main() |
| OLD | NEW |