blob: 81afcdddc8b59a41f0dcb8ce85c995fd839bd3c7 [file] [log] [blame]
// 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 syntax documents the syntax used by benchmark filter and
// projection expressions.
//
// These expressions work with benchmark data in the Go benchmark
// format (https://golang.org/design/14313-benchmark-format). Each
// benchmark result (a line beginning with "Benchmark") consists of
// several field, including a name, name-based configuration, and
// file configuration pairs ("key: value" lines).
//
// # Keys
//
// Filters and projections share a common set of keys for referring to
// these fields of a benchmark result:
//
// - ".name" refers to the benchmark name, excluding per-benchmark
// configuration. For example, the ".name" of the
// "BenchmarkCopy/size=4k-16" benchmark is "Copy".
//
// - ".fullname" refers to the full benchmark name, including
// per-benchmark configuration, but excluding the "Benchmark" prefix.
// For example, the ".fullname" of "BenchmarkCopy/size=4k-16" is
// "Copy/size=4k-16".
//
// - "/{key}" refers to value of {key} from the benchmark name
// configuration. For example, the "/size" of
// "BenchmarkCopy/size=4k-16", is "4k". As a special case,
// "/gomaxprocs" recognizes both a literal "/gomaxprocs=" in the name,
// and the "-N" convention. For the above example, "/gomaxprocs" is
// "16".
//
// - Any name NOT prefixed with "/" or "." refers to the value of a
// file configuration key. For example, the "testing" package
// automatically emits a few file configuration keys, including "pkg",
// "goos", and "goarch", so the projection "pkg" extracts the package
// path of a benchmark.
//
// - ".config" (only in projections) refers to the all file
// configuration keys of a benchmark. The value of .config isn't a
// string like the other fields, but rather a tuple. .config is useful
// for grouping results by all file configuration keys to avoid grouping
// together incomparable results. For example, benchstat separates
// results with different .config into different tables.
//
// - ".unit" (only in filters) refers to individual measurements in a
// result, such as the "ns/op" measurement. The filter ".unit:ns/op"
// extracts just the ns/op measurement of a result. This will match
// both original units (e.g., "ns/op") and tidied units (e.g.,
// "sec/op").
//
// - ".file" refers to the input file provided on the command line
// (for command-line tools that use benchfmt.Files).
//
// # Filters
//
// Filters are boolean expressions that match or exclude benchmark
// results or individual measurements.
//
// Filters are built from key-value terms:
//
// key:value - Match if key's value is exactly "value".
// key:"value" - Same, but value is a double-quoted Go string that
// may contain spaces or other special characters.
// "key":value - Keys may also be double-quoted.
// key:/regexp/ - Match if key's value matches a regular expression.
// key:(val1 OR val2 OR ...)
// - Short-hand for key:val1 OR key:val2. Values may be
// double-quoted strings or regexps.
// * - Match everything.
//
// These terms can be combined into larger expressions as follows:
//
// x y ... - Match if x, y, etc. all match.
// x AND y - Same as x y.
// x OR y - Match if x or y match.
// -x - Match if x does not match.
// (...) - Subexpression.
//
// Precise syntax:
//
// expr = andExpr {"OR" andExpr}
// andExpr = match {"AND"? match}
// match = "(" expr ")"
// | "-" match
// | "*"
// | key ":" value
// | key ":" "(" value {"OR" value} ")"
// key = word
// value = word
// | "/" regexp "/"
//
// # Projections
//
// A projection expresses how to extract a tuple of data from a
// benchmark result, as well as a sort order for projected tuples.
//
// A projection is a comma- or space-separated list of fields.
// Each field specifies a key and optionally a sort order and a
// filter as follows:
//
// - "key" extracts the named field and orders it using the order
// values of this key are first observed in the data.
//
// - "key@order" specifies one of the built-in named sort orders. This
// can be "alpha" or "num" for alphabetic or numeric sorting. "num"
// understands basic use of metric and IEC prefixes like "2k" and
// "1Mi".
//
// - "key@(value value ...)" specifies a fixed value order for key.
// It also specifies a filter: if key has a value that isn't any of
// the specified values, the result is filtered out.
//
// Precise syntax:
//
// expr = part {","? part}
// part = key
// | key "@" order
// | key "@" "(" word {word} ")"
// key = word
// order = word
//
// # Common syntax
//
// Filters and projections share the following common base syntax:
//
// word = bareWord
// | double-quoted Go string
// bareWord = [^-*"():@,][^ ():@,]*
package syntax