Documentation ¶
Overview ¶
Package benchfmt provides a high-performance reader and writer for the Go benchmark format.
This implements the format documented at https://golang.org/design/14313-benchmark-format.
The reader and writer are structured as streaming operations to allow incremental processing and avoid dictating a data model. This allows consumers of these APIs to provide their own data model best suited to its needs. The reader also performs in-place updates to reduce allocation, enabling it to parse millions of benchmark results per second on a typical laptop.
This package is designed to be used with the higher-level packages benchunit, benchmath, and benchproc.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct { Key string Value []byte File bool // Set if this is a file configuration key, otherwise internal }
A Config is a single key/value configuration pair. This can be a file configuration, which was read directly from a benchmark results file; or an "internal" configuration that was supplied by tooling.
type Files ¶
type Files struct { // Paths is the list of file names to read in. // // If AllowLabels is set, these strings may be of the form // label=path, and the label part will be used for the // ".file" key in the results. Paths []string // AllowStdin indicates that the path "-" should be treated as // stdin and if the file list is empty, it should be treated // as consisting of stdin. // // This is generally the desired behavior when the file list // comes from command-line flags. AllowStdin bool // AllowLabels indicates that custom labels are allowed in // Paths. // // This is generally the desired behavior when the file list // comes from command-line flags, as it allows users to // override .file. AllowLabels bool // contains filtered or unexported fields }
A Files reads benchmark results from a sequence of input files.
This reader adds a ".file" configuration key to the output Results corresponding to each path read in. By default, this will be the file name directly from Paths, except that duplicate strings will be disambiguated by appending "#N". If AllowLabels is true, then entries in Path may be of the form label=path, and the label part will be used for .file (without any disambiguation).
func (*Files) Err ¶
Err returns the I/O error that stopped Scan, if any. If Scan stopped because it read each file to completion, or if Scan has not yet returned false, Err returns nil.
func (*Files) Scan ¶
Scan advances the reader to the next result in the sequence of files and reports whether a result was read. The caller should use the Result method to get the result. If Scan reaches the end of the file sequence, or if an I/O error occurs, it returns false. In this case, the caller should use the Err method to check for errors.
func (*Files) Units ¶
func (f *Files) Units() map[UnitMetadataKey]*UnitMetadata
Units returns the accumulated unit metadata. See Reader.Units.
type Name ¶
type Name []byte
A Name is a full benchmark name, including all sub-benchmark configuration.
func (Name) Base ¶
Base returns the base part of a full benchmark name, without any configuration keys or GOMAXPROCS.
func (Name) Full ¶
Full returns the full benchmark name as a []byte. This is simply the value of n, but helps with code readability.
func (Name) Parts ¶
Parts splits a benchmark name into the base name and sub-benchmark configuration parts. Each sub-benchmark configuration part is one of three forms:
1. "/<key>=<value>" indicates a key/value configuration pair.
2. "/<string>" indicates a positional configuration pair.
3. "-<gomaxprocs>" indicates the GOMAXPROCS of this benchmark. This part can only appear last.
Concatenating the base name and the configuration parts reconstructs the full name.
type Reader ¶
type Reader struct {
// contains filtered or unexported fields
}
A Reader reads the Go benchmark format.
Its API is modeled on bufio.Scanner. To minimize allocation, a Reader retains ownership of everything it creates; a caller should copy anything it needs to retain.
To construct a new Reader, either call NewReader, or call Reset on a zeroed Reader.
func NewReader ¶
NewReader constructs a reader to parse the Go benchmark format from r. fileName is used in error messages; it is purely diagnostic.
func (*Reader) Reset ¶
Reset resets the reader to begin reading from a new input. It also resets all accumulated configuration values. It does NOT reset unit metadata because it carries across files.
initConfig is an alternating sequence of keys and values. Reset will install these as the initial internal configuration before any results are read from the input file.
func (*Reader) Result ¶
Result returns the record that was just read by Scan. This is either a *Result, a *UnitMetadata, or a *SyntaxError indicating a parse error. It may return more types in the future.
Parse errors are non-fatal, so the caller can continue to call Scan.
If this returns a *Result, the caller should not retain the Result, as it will be overwritten by the next call to Scan.
func (*Reader) Scan ¶
Scan advances the reader to the next result and reports whether a result was read. The caller should use the Result method to get the result. If Scan reaches EOF or an I/O error occurs, it returns false, in which case the caller should use the Err method to check for errors.
func (*Reader) Units ¶
func (r *Reader) Units() UnitMetadataMap
Units returns the accumulated unit metadata.
Callers that want to consume the entire stream of benchmark results and then process units can use this instead of monitoring *UnitMetadata Records.
type Record ¶
type Record interface { // Pos returns the position of this record as a file name and a // 1-based line number within that file. If this record was not read // from a file, it returns "", 0. Pos() (fileName string, line int) }
A Record is a single record read from a benchmark file. It may be a *Result or a *SyntaxError.
type Result ¶
type Result struct { // Config is the set of key/value configuration pairs for this result, // including file and internal configuration. This does not include // sub-name configuration. // // This slice is mutable, as are the values in the slice. // Result internally maintains an index of the keys of this slice, // so callers must use SetConfig to add or delete keys, // but may modify values in place. There is one exception to this: // for convenience, new Results can be initialized directly, // e.g., using a struct literal. // // SetConfig appends new keys to this slice and updates existing ones // in place. To delete a key, it swaps the deleted key with // the final slice element. This way, the order of these keys is // deterministic. Config []Config // Name is the full name of this benchmark, including all // sub-benchmark configuration. Name Name // Iters is the number of iterations this benchmark's results // were averaged over. Iters int // Values is this benchmark's measurements and their units. Values []Value // contains filtered or unexported fields }
A Result is a single benchmark result and all of its measurements.
Results are designed to be mutated in place and reused to reduce allocation.
func (*Result) ConfigIndex ¶
ConfigIndex returns the index in r.Config of key.
func (*Result) GetConfig ¶
GetConfig returns the value of a configuration key, or "" if not present.
func (*Result) Pos ¶
Pos returns the file name and line number of a Result that was read by a Reader. For Results that were not read from a file, it returns "", 0.
type SyntaxError ¶
A SyntaxError represents a syntax error on a particular line of a benchmark results file.
func (*SyntaxError) Error ¶
func (s *SyntaxError) Error() string
func (*SyntaxError) Pos ¶
func (e *SyntaxError) Pos() (fileName string, line int)
type UnitMetadata ¶
type UnitMetadata struct { UnitMetadataKey // OrigUnit is the original, untidied unit as written in the input. OrigUnit string Value string // contains filtered or unexported fields }
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`.
func (*UnitMetadata) Pos ¶
func (u *UnitMetadata) Pos() (fileName string, line int)
type UnitMetadataKey ¶
UnitMetadataKey identifies a single piece of unit metadata by unit and metadata name.
type UnitMetadataMap ¶
type UnitMetadataMap map[UnitMetadataKey]*UnitMetadata
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.
func (UnitMetadataMap) Get ¶
func (m UnitMetadataMap) Get(unit, key string) *UnitMetadata
Get returns the unit metadata for the specified unit and metadata key. It tidies unit if necessary.
func (UnitMetadataMap) GetAssumption ¶
func (m UnitMetadataMap) GetAssumption(unit string) benchmath.Assumption
GetAssumption returns the appropriate statistical Assumption to make about distributions of values in the given unit.
func (UnitMetadataMap) GetBetter ¶
func (m UnitMetadataMap) GetBetter(unit string) int
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.
type Value ¶
type Value struct { Value float64 Unit string // OrigValue and OrigUnit, if non-zero, give the original, // untidied value and unit, typically as read from the // original input. OrigUnit may be "", indicating that the // value wasn't transformed. OrigValue float64 OrigUnit string }
A Value is a single value/unit measurement from a benchmark result.
Values should be tidied to use base units like "sec" and "B" when constructed. Reader ensures this.
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
A Writer writes the Go benchmark format.
func (*Writer) Write ¶
Write writes Record rec to w. If rec is a *Result and rec's file configuration differs from the current file configuration in w, it first emits the appropriate file configuration lines. For Result.Values that have a non-zero OrigUnit, this uses OrigValue and OrigUnit in order to better reproduce the original input.