forked from cespare/prettybench
/
prettybench.go
86 lines (70 loc) · 2.2 KB
/
prettybench.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package main
import (
"bufio"
"errors"
"flag"
"fmt"
"os"
"regexp"
"strings"
"github.com/KEINOS/go-prettybench/prettify"
"golang.org/x/tools/benchmark/parse"
)
var (
errNotBenchLine = errors.New("not a bench line")
// Regular expression to find bench data lines.
benchLineMatcher = regexp.MustCompile(`^Benchmark.*\t.*\d+`)
// Regular expression to find the test result.
okLineMatcher = regexp.MustCompile(`^ok\s`)
// Flag options.
noPassthrough = flag.Bool("no-passthrough", false, "Don't print non-benchmark lines")
sortColumn = flag.String("sort", "", "Sort by column (string: name, iter, time, bytes, allocs)")
// OsSTDIN is a copy of os.Stdin to ease mocking in tests.
OsSTDIN = os.Stdin
// OsExit is a copy of os.Exit to ease mocking in tests.
OsExit = os.Exit
)
func main() {
flag.Parse()
currentBenchmark := &prettify.BenchOutputGroup{}
scanner := bufio.NewScanner(OsSTDIN)
currentBenchmark.ColNameSort = *sortColumn
// Loop each line of bench results from the input and print the parsed output
for scanner.Scan() {
lineText := scanner.Text()
lineParsed, err := ParseLine(lineText)
switch err {
case errNotBenchLine:
// Spit out the parsed lines if the line reaches to test result ans is "ok"
if okLineMatcher.MatchString(lineText) {
fmt.Print(currentBenchmark) // Call stringer and print it
currentBenchmark = &prettify.BenchOutputGroup{} // Reset
}
// Print if noPassthrough flag is false (print info)
if !*noPassthrough {
fmt.Println(lineText)
}
case nil:
currentBenchmark.AddLine(lineParsed)
default:
fmt.Fprintln(os.Stderr, "prettybench unrecognized line:")
fmt.Println(lineText)
}
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "prettybench unrecognized line:", err)
OsExit(1)
}
}
// ParseLine parses a line of benchmark output to testing.Benchmark.
// It returns an errNotBenchLine error if the line doesn't seem to contain benchmark data.
func ParseLine(line string) (*parse.Benchmark, error) {
if !benchLineMatcher.MatchString(line) {
return nil, errNotBenchLine
}
fields := strings.Split(line, "\t")
if len(fields) < 3 {
return nil, errNotBenchLine
}
return parse.ParseLine(line)
}