Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / benchmark / parse / parse.go
1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Package parse provides support for parsing benchmark results as
6 // generated by 'go test -bench'.
7 package parse // import "golang.org/x/tools/benchmark/parse"
8
9 import (
10         "bufio"
11         "bytes"
12         "fmt"
13         "io"
14         "strconv"
15         "strings"
16 )
17
18 // Flags used by Benchmark.Measured to indicate
19 // which measurements a Benchmark contains.
20 const (
21         NsPerOp = 1 << iota
22         MBPerS
23         AllocedBytesPerOp
24         AllocsPerOp
25 )
26
27 // Benchmark is one run of a single benchmark.
28 type Benchmark struct {
29         Name              string  // benchmark name
30         N                 int     // number of iterations
31         NsPerOp           float64 // nanoseconds per iteration
32         AllocedBytesPerOp uint64  // bytes allocated per iteration
33         AllocsPerOp       uint64  // allocs per iteration
34         MBPerS            float64 // MB processed per second
35         Measured          int     // which measurements were recorded
36         Ord               int     // ordinal position within a benchmark run
37 }
38
39 // ParseLine extracts a Benchmark from a single line of testing.B
40 // output.
41 func ParseLine(line string) (*Benchmark, error) {
42         fields := strings.Fields(line)
43
44         // Two required, positional fields: Name and iterations.
45         if len(fields) < 2 {
46                 return nil, fmt.Errorf("two fields required, have %d", len(fields))
47         }
48         if !strings.HasPrefix(fields[0], "Benchmark") {
49                 return nil, fmt.Errorf(`first field does not start with "Benchmark"`)
50         }
51         n, err := strconv.Atoi(fields[1])
52         if err != nil {
53                 return nil, err
54         }
55         b := &Benchmark{Name: fields[0], N: n}
56
57         // Parse any remaining pairs of fields; we've parsed one pair already.
58         for i := 1; i < len(fields)/2; i++ {
59                 b.parseMeasurement(fields[i*2], fields[i*2+1])
60         }
61         return b, nil
62 }
63
64 func (b *Benchmark) parseMeasurement(quant string, unit string) {
65         switch unit {
66         case "ns/op":
67                 if f, err := strconv.ParseFloat(quant, 64); err == nil {
68                         b.NsPerOp = f
69                         b.Measured |= NsPerOp
70                 }
71         case "MB/s":
72                 if f, err := strconv.ParseFloat(quant, 64); err == nil {
73                         b.MBPerS = f
74                         b.Measured |= MBPerS
75                 }
76         case "B/op":
77                 if i, err := strconv.ParseUint(quant, 10, 64); err == nil {
78                         b.AllocedBytesPerOp = i
79                         b.Measured |= AllocedBytesPerOp
80                 }
81         case "allocs/op":
82                 if i, err := strconv.ParseUint(quant, 10, 64); err == nil {
83                         b.AllocsPerOp = i
84                         b.Measured |= AllocsPerOp
85                 }
86         }
87 }
88
89 func (b *Benchmark) String() string {
90         buf := new(bytes.Buffer)
91         fmt.Fprintf(buf, "%s %d", b.Name, b.N)
92         if (b.Measured & NsPerOp) != 0 {
93                 fmt.Fprintf(buf, " %.2f ns/op", b.NsPerOp)
94         }
95         if (b.Measured & MBPerS) != 0 {
96                 fmt.Fprintf(buf, " %.2f MB/s", b.MBPerS)
97         }
98         if (b.Measured & AllocedBytesPerOp) != 0 {
99                 fmt.Fprintf(buf, " %d B/op", b.AllocedBytesPerOp)
100         }
101         if (b.Measured & AllocsPerOp) != 0 {
102                 fmt.Fprintf(buf, " %d allocs/op", b.AllocsPerOp)
103         }
104         return buf.String()
105 }
106
107 // Set is a collection of benchmarks from one
108 // testing.B run, keyed by name to facilitate comparison.
109 type Set map[string][]*Benchmark
110
111 // ParseSet extracts a Set from testing.B output.
112 // ParseSet preserves the order of benchmarks that have identical
113 // names.
114 func ParseSet(r io.Reader) (Set, error) {
115         bb := make(Set)
116         scan := bufio.NewScanner(r)
117         ord := 0
118         for scan.Scan() {
119                 if b, err := ParseLine(scan.Text()); err == nil {
120                         b.Ord = ord
121                         ord++
122                         bb[b.Name] = append(bb[b.Name], b)
123                 }
124         }
125
126         if err := scan.Err(); err != nil {
127                 return nil, err
128         }
129
130         return bb, nil
131 }