From a1b20e1df03ddf5530c7e1ad2e882943fa100593 Mon Sep 17 00:00:00 2001 From: mlippautz Date: Fri, 25 Sep 2015 09:14:03 -0700 Subject: [PATCH] [tools] Add capability of generating log2-based histograms to eval_gc_nvp.py BUG= Review URL: https://codereview.chromium.org/1372623002 Cr-Commit-Position: refs/heads/master@{#30949} --- tools/eval_gc_nvp.py | 101 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 69 insertions(+), 32 deletions(-) diff --git a/tools/eval_gc_nvp.py b/tools/eval_gc_nvp.py index 047a6df..8a9b8e7 100755 --- a/tools/eval_gc_nvp.py +++ b/tools/eval_gc_nvp.py @@ -10,17 +10,47 @@ from argparse import ArgumentParser from copy import deepcopy from gc_nvp_common import split_nvp +from math import log from sys import stdin -class Histogram: - def __init__(self, granularity, fill_empty): +class LinearBucket: + def __init__(self, granularity): self.granularity = granularity + + def value_to_bucket(self, value): + return int(value / self.granularity) + + def bucket_to_range(self, bucket): + return (bucket * self.granularity, (bucket + 1) * self.granularity) + + +class Log2Bucket: + def __init__(self, start): + self.start = int(log(start, 2)) - 1 + + def value_to_bucket(self, value): + index = int(log(value, 2)) + index -= self.start + if index < 0: + index = 0 + return index + + def bucket_to_range(self, bucket): + if bucket == 0: + return (0, 2 ** (self.start + 1)) + bucket += self.start + return (2 ** bucket, 2 ** (bucket + 1)) + + +class Histogram: + def __init__(self, bucket_trait, fill_empty): self.histogram = {} self.fill_empty = fill_empty + self.bucket_trait = bucket_trait def add(self, key): - index = int(key / self.granularity) + index = self.bucket_trait.value_to_bucket(key) if index not in self.histogram: self.histogram[index] = 0 self.histogram[index] += 1 @@ -29,20 +59,17 @@ class Histogram: ret = [] keys = self.histogram.keys() keys.sort() - last = -self.granularity - for key in keys: - min_value = key * self.granularity - max_value = min_value + self.granularity - - if self.fill_empty: - while (last + self.granularity) != min_value: - last += self.granularity + last = keys[len(keys) - 1] + for i in range(0, last + 1): + (min_value, max_value) = self.bucket_trait.bucket_to_range(i) + if i == keys[0]: + keys.pop(0) + ret.append(" [{0},{1}[: {2}".format( + str(min_value), str(max_value), self.histogram[i])) + else: + if self.fill_empty: ret.append(" [{0},{1}[: {2}".format( - str(last), str(last + self.granularity), 0)) - - ret.append(" [{0},{1}[: {2}".format( - str(min_value), str(max_value), self.histogram[key])) - last = min_value + str(min_value), str(max_value), 0)) return "\n".join(ret) @@ -73,27 +100,37 @@ class Category: def main(): parser = ArgumentParser(description="Process GCTracer's NVP output") parser.add_argument('keys', metavar='KEY', type=str, nargs='+', - help='the keys (names) to process') - parser.add_argument('--histogram-granularity', metavar='GRANULARITY', - type=int, nargs='?', default=5, - help='histogram granularity (default: 5)') - parser.add_argument('--no-histogram-print-empty', dest='histogram_print_empty', - action='store_false', - help='print empty histogram buckets') - feature_parser = parser.add_mutually_exclusive_group(required=False) - feature_parser.add_argument('--histogram', dest='histogram', - action='store_true', - help='print histogram') - feature_parser.add_argument('--no-histogram', dest='histogram', - action='store_false', - help='do not print histogram') + help='the keys of NVPs to process') + parser.add_argument('--histogram-type', metavar='', + type=str, nargs='?', default="linear", + help='histogram type to use (default: linear)') + linear_group = parser.add_argument_group('linear histogram specific') + linear_group.add_argument('--linear-histogram-granularity', + metavar='GRANULARITY', type=int, nargs='?', + default=5, + help='histogram granularity (default: 5)') + log2_group = parser.add_argument_group('log2 histogram specific') + log2_group.add_argument('--log2-histogram-init-bucket', metavar='START', + type=int, nargs='?', default=64, + help='initial buck size (default: 64)') + parser.add_argument('--histogram-omit-empty-buckets', + dest='histogram_omit_empty', + action='store_true', + help='omit empty histogram buckets') + parser.add_argument('--no-histogram', dest='histogram', + action='store_false', help='do not print histogram') parser.set_defaults(histogram=True) - parser.set_defaults(histogram_print_empty=True) + parser.set_defaults(histogram_omit_empty=False) args = parser.parse_args() histogram = None if args.histogram: - histogram = Histogram(args.histogram_granularity, args.histogram_print_empty) + bucket_trait = None + if args.histogram_type == "log2": + bucket_trait = Log2Bucket(args.log2_histogram_init_bucket) + else: + bucket_trait = LinearBucket(args.linear_histogram_granularity) + histogram = Histogram(bucket_trait, not args.histogram_omit_empty) categories = [ Category(key, deepcopy(histogram)) for key in args.keys ] -- 2.7.4