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 |