OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # Copyright 2016 the V8 project authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. |
| 5 ''' |
| 6 (You'll need packages python-numpy and python-scipy.) |
| 7 |
| 8 This is a script for comparing v8-perf statistics for benchmarks run |
| 9 on different versions of V8. Here's an example of how it can be used: |
| 10 |
| 11 ```bash |
| 12 cd v8-perf/benchmarks/Octane2.1 |
| 13 loop -100 ~/vanilla/v8/out/Release/d8 run-some.js -- code-load > vanilla.txt |
| 14 loop -100 ~/v8/out/Release/d8 run-some.js -- code-load > modified.txt |
| 15 ./v8-perf-statistics.py vanilla.txt modified.txt |
| 16 ``` |
| 17 |
| 18 where I have defined `loop` to be: |
| 19 |
| 20 ```bash |
| 21 function loop () { |
| 22 limit=10 |
| 23 case "$1" in |
| 24 -*) |
| 25 limit="${1#-}" |
| 26 shift |
| 27 esac |
| 28 for ((i=1; i<=$limit; i++)); do |
| 29 printf "%5d " $i |
| 30 $* |
| 31 done |
| 32 } |
| 33 ``` |
| 34 |
| 35 Multiple files can be supplied to the command line. The base file is |
| 36 taken to be the first, but you can change this, e.g. |
| 37 |
| 38 ```bash |
| 39 ./v8-perf-statistics.py -2 modified-1.txt vanilla.txt modified-2.txt |
| 40 ``` |
| 41 ''' |
| 42 |
| 43 import numpy, scipy, scipy.stats |
| 44 from math import sqrt |
| 45 |
| 46 def statistics(data): |
| 47 N = len(data) |
| 48 average = numpy.average(data) |
| 49 median = numpy.median(data) |
| 50 low = numpy.min(data) |
| 51 high= numpy.max(data) |
| 52 # evaluate sample variance by setting delta degrees of freedom (ddof) to |
| 53 # 1. The degree used in calculations is N - ddof |
| 54 stdev = numpy.std(data, ddof=1) |
| 55 # Get the endpoints of the range that contains 95% of the distribution |
| 56 t_bounds = scipy.stats.t.interval(0.95, N-1) |
| 57 # sum mean to the confidence interval |
| 58 ci = [average + critval * stdev / sqrt(N) for critval in t_bounds] |
| 59 return N, average, median, stdev, low, high, ci |
| 60 |
| 61 import re, sys |
| 62 |
| 63 F = [] |
| 64 T = {} |
| 65 base = 0 |
| 66 |
| 67 # Match e.g. "CodeLoad-octane2.1(Score): 13761" |
| 68 # Allow for an optional number in front, e.g. "1 RegExp-octane2.1(Score): 4951" |
| 69 R = re.compile("\s*(\d+)?\s*([^:]*):\s*(\d+(.\d+)?)\s*") |
| 70 |
| 71 for arg in sys.argv[1:]: |
| 72 if arg[0] == "-": |
| 73 base = int(arg[1:]) - 1 |
| 74 continue |
| 75 F.append(arg) |
| 76 with open(arg, "rt") as f: |
| 77 S = {} |
| 78 for line in f: |
| 79 # Ignore empty lines. |
| 80 if not line.strip(): continue |
| 81 # Ignore lines printed by the run_perf.py tool. |
| 82 if line.startswith(">>> ") or line.startswith("{"): continue |
| 83 # The rest should come from the run.js script. |
| 84 m = R.match(line) |
| 85 assert m |
| 86 key = m.group(2) |
| 87 value = int(m.group(3)) |
| 88 if key not in S: S[key] = [] |
| 89 S[key].append(value) |
| 90 for key, values in S.items(): |
| 91 if key not in T: T[key] = {} |
| 92 T[key][arg] = statistics(values) |
| 93 |
| 94 base = F[base] |
| 95 |
| 96 for key in T: |
| 97 print key |
| 98 for arg in F: |
| 99 def compare(i): |
| 100 if arg == base: |
| 101 return T[key][arg][i], "base" |
| 102 diff = T[key][arg][i] - T[key][base][i] |
| 103 perc = 100.0 * diff / T[key][base][i] |
| 104 return T[key][arg][i], "{:+6.2f}".format(perc) |
| 105 print " {}:".format(arg) |
| 106 print " samples: {:5}".format(T[key][arg][0]) |
| 107 print " average: {:8.2f} {}".format(*compare(1)) |
| 108 print " median: {:8.2f} {}".format(*compare(2)) |
| 109 print " stddev: {:8.2f} {}".format(*compare(3)) |
| 110 print " minimum: {:5} {}".format(*compare(4)) |
| 111 print " maximum: {:5} {}".format(*compare(5)) |
| 112 print " CI 95%: {:8.2f} to {:8.2f}".format(*T[key][arg][6]) |
OLD | NEW |