-
Notifications
You must be signed in to change notification settings - Fork 53
/
Copy pathunits.go
99 lines (87 loc) · 2.92 KB
/
units.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
87
88
89
90
91
92
93
94
95
96
97
98
99
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package benchfmt
import (
"golang.org/x/perf/benchmath"
"golang.org/x/perf/benchunit"
)
// Unit metadata is a single piece of unit metadata.
//
// Unit metadata gives information that's useful to interpreting
// values in a given unit. The following metadata keys are predefined:
//
// better={higher,lower} indicates whether higher or lower values of
// this unit are better (indicate an improvement).
//
// assume={nothing,exact} indicates what statistical assumption to
// make when considering distributions of values.
// `nothing` means to make no statistical assumptions (e.g., use
// non-parametric methods) and `exact` means to assume measurements are
// exact (repeated measurement does not increase confidence).
// The default is `nothing`.
type UnitMetadata struct {
UnitMetadataKey
// OrigUnit is the original, untidied unit as written in the input.
OrigUnit string
Value string
fileName string
line int
}
func (u *UnitMetadata) Pos() (fileName string, line int) {
return u.fileName, u.line
}
// UnitMetadataKey identifies a single piece of unit metadata by unit
// and metadata name.
type UnitMetadataKey struct {
Unit string
Key string // Metadata key (e.g., "better" or "assume")
}
// UnitMetadataMap stores the accumulated metadata for several units.
// This is indexed by tidied units, while the values store the original
// units from the benchmark file.
type UnitMetadataMap map[UnitMetadataKey]*UnitMetadata
// Get returns the unit metadata for the specified unit and metadata key.
// It tidies unit if necessary.
func (m UnitMetadataMap) Get(unit, key string) *UnitMetadata {
_, tidyUnit := benchunit.Tidy(1, unit)
return m[UnitMetadataKey{tidyUnit, key}]
}
// GetAssumption returns the appropriate statistical Assumption to make
// about distributions of values in the given unit.
func (m UnitMetadataMap) GetAssumption(unit string) benchmath.Assumption {
dist := m.Get(unit, "assume")
if dist != nil && dist.Value == "exact" {
return benchmath.AssumeExact
}
// The default is to assume nothing.
return benchmath.AssumeNothing
}
// GetBetter returns whether higher or lower values of the given unit
// indicate an improvement. It returns +1 if higher values are better,
// -1 if lower values are better, or 0 if unknown.
func (m UnitMetadataMap) GetBetter(unit string) int {
better := m.Get(unit, "better")
if better != nil {
switch better.Value {
case "higher":
return 1
case "lower":
return -1
}
return 0
}
// Fall back to some built-in defaults.
switch unit {
case "ns/op", "sec/op":
// This measures "duration", so lower is better.
return -1
case "MB/s", "B/s":
// This measures "speed", so higher is better.
return 1
case "B/op", "allocs/op":
// These measure amount of allocation, so lower is better.
return -1
}
return 0
}