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 |
10 from argparse import ArgumentParser | 10 from argparse import ArgumentParser |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 self.key = key | 78 self.key = key |
79 self.values = [] | 79 self.values = [] |
80 self.histogram = histogram | 80 self.histogram = histogram |
81 | 81 |
82 def process_entry(self, entry): | 82 def process_entry(self, entry): |
83 if self.key in entry: | 83 if self.key in entry: |
84 self.values.append(float(entry[self.key])) | 84 self.values.append(float(entry[self.key])) |
85 if self.histogram: | 85 if self.histogram: |
86 self.histogram.add(float(entry[self.key])) | 86 self.histogram.add(float(entry[self.key])) |
87 | 87 |
| 88 def min(self): |
| 89 return min(self.values) |
| 90 |
| 91 def max(self): |
| 92 return max(self.values) |
| 93 |
| 94 def avg(self): |
| 95 return sum(self.values) / len(self.values) |
| 96 |
88 def __str__(self): | 97 def __str__(self): |
89 ret = [self.key] | 98 ret = [self.key] |
90 ret.append(" len: {0}".format(len(self.values))) | 99 ret.append(" len: {0}".format(len(self.values))) |
91 if len(self.values) > 0: | 100 if len(self.values) > 0: |
92 ret.append(" min: {0}".format(min(self.values))) | 101 ret.append(" min: {0}".format(min(self.values))) |
93 ret.append(" max: {0}".format(max(self.values))) | 102 ret.append(" max: {0}".format(max(self.values))) |
94 ret.append(" avg: {0}".format(sum(self.values) / len(self.values))) | 103 ret.append(" avg: {0}".format(sum(self.values) / len(self.values))) |
95 if self.histogram: | 104 if self.histogram: |
96 ret.append(str(self.histogram)) | 105 ret.append(str(self.histogram)) |
97 return "\n".join(ret) | 106 return "\n".join(ret) |
98 | 107 |
| 108 def __repr__(self): |
| 109 return "<Category: {0}>".format(self.key) |
| 110 |
| 111 |
| 112 def make_key_func(cmp_metric): |
| 113 def key_func(a): |
| 114 return getattr(a, cmp_metric)() |
| 115 return key_func |
| 116 |
99 | 117 |
100 def main(): | 118 def main(): |
101 parser = ArgumentParser(description="Process GCTracer's NVP output") | 119 parser = ArgumentParser(description="Process GCTracer's NVP output") |
102 parser.add_argument('keys', metavar='KEY', type=str, nargs='+', | 120 parser.add_argument('keys', metavar='KEY', type=str, nargs='+', |
103 help='the keys of NVPs to process') | 121 help='the keys of NVPs to process') |
104 parser.add_argument('--histogram-type', metavar='<linear|log2>', | 122 parser.add_argument('--histogram-type', metavar='<linear|log2>', |
105 type=str, nargs='?', default="linear", | 123 type=str, nargs='?', default="linear", |
106 help='histogram type to use (default: linear)') | 124 help='histogram type to use (default: linear)') |
107 linear_group = parser.add_argument_group('linear histogram specific') | 125 linear_group = parser.add_argument_group('linear histogram specific') |
108 linear_group.add_argument('--linear-histogram-granularity', | 126 linear_group.add_argument('--linear-histogram-granularity', |
109 metavar='GRANULARITY', type=int, nargs='?', | 127 metavar='GRANULARITY', type=int, nargs='?', |
110 default=5, | 128 default=5, |
111 help='histogram granularity (default: 5)') | 129 help='histogram granularity (default: 5)') |
112 log2_group = parser.add_argument_group('log2 histogram specific') | 130 log2_group = parser.add_argument_group('log2 histogram specific') |
113 log2_group.add_argument('--log2-histogram-init-bucket', metavar='START', | 131 log2_group.add_argument('--log2-histogram-init-bucket', metavar='START', |
114 type=int, nargs='?', default=64, | 132 type=int, nargs='?', default=64, |
115 help='initial buck size (default: 64)') | 133 help='initial buck size (default: 64)') |
116 parser.add_argument('--histogram-omit-empty-buckets', | 134 parser.add_argument('--histogram-omit-empty-buckets', |
117 dest='histogram_omit_empty', | 135 dest='histogram_omit_empty', |
118 action='store_true', | 136 action='store_true', |
119 help='omit empty histogram buckets') | 137 help='omit empty histogram buckets') |
120 parser.add_argument('--no-histogram', dest='histogram', | 138 parser.add_argument('--no-histogram', dest='histogram', |
121 action='store_false', help='do not print histogram') | 139 action='store_false', help='do not print histogram') |
122 parser.set_defaults(histogram=True) | 140 parser.set_defaults(histogram=True) |
123 parser.set_defaults(histogram_omit_empty=False) | 141 parser.set_defaults(histogram_omit_empty=False) |
| 142 parser.add_argument('--rank', metavar='<no|min|max|avg>', |
| 143 type=str, nargs='?', |
| 144 default="no", |
| 145 help="rank keys by metric (default: no)") |
124 args = parser.parse_args() | 146 args = parser.parse_args() |
125 | 147 |
126 histogram = None | 148 histogram = None |
127 if args.histogram: | 149 if args.histogram: |
128 bucket_trait = None | 150 bucket_trait = None |
129 if args.histogram_type == "log2": | 151 if args.histogram_type == "log2": |
130 bucket_trait = Log2Bucket(args.log2_histogram_init_bucket) | 152 bucket_trait = Log2Bucket(args.log2_histogram_init_bucket) |
131 else: | 153 else: |
132 bucket_trait = LinearBucket(args.linear_histogram_granularity) | 154 bucket_trait = LinearBucket(args.linear_histogram_granularity) |
133 histogram = Histogram(bucket_trait, not args.histogram_omit_empty) | 155 histogram = Histogram(bucket_trait, not args.histogram_omit_empty) |
134 | 156 |
135 categories = [ Category(key, deepcopy(histogram)) | 157 categories = [ Category(key, deepcopy(histogram)) |
136 for key in args.keys ] | 158 for key in args.keys ] |
137 | 159 |
138 while True: | 160 while True: |
139 line = stdin.readline() | 161 line = stdin.readline() |
140 if not line: | 162 if not line: |
141 break | 163 break |
142 obj = split_nvp(line) | 164 obj = split_nvp(line) |
143 for category in categories: | 165 for category in categories: |
144 category.process_entry(obj) | 166 category.process_entry(obj) |
145 | 167 |
| 168 if args.rank != "no": |
| 169 categories = sorted(categories, key=make_key_func(args.rank), reverse=True) |
| 170 |
146 for category in categories: | 171 for category in categories: |
147 print(category) | 172 print(category) |
148 | 173 |
149 | 174 |
150 if __name__ == '__main__': | 175 if __name__ == '__main__': |
151 main() | 176 main() |
OLD | NEW |