mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 13:50:01 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			132 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2014 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 parse provides support for parsing benchmark results as
 | |
| // generated by 'go test -bench'.
 | |
| package parse // import "golang.org/x/tools/benchmark/parse"
 | |
| 
 | |
| import (
 | |
| 	"bufio"
 | |
| 	"bytes"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| )
 | |
| 
 | |
| // Flags used by Benchmark.Measured to indicate
 | |
| // which measurements a Benchmark contains.
 | |
| const (
 | |
| 	NsPerOp = 1 << iota
 | |
| 	MBPerS
 | |
| 	AllocedBytesPerOp
 | |
| 	AllocsPerOp
 | |
| )
 | |
| 
 | |
| // Benchmark is one run of a single benchmark.
 | |
| type Benchmark struct {
 | |
| 	Name              string  // benchmark name
 | |
| 	N                 int     // number of iterations
 | |
| 	NsPerOp           float64 // nanoseconds per iteration
 | |
| 	AllocedBytesPerOp uint64  // bytes allocated per iteration
 | |
| 	AllocsPerOp       uint64  // allocs per iteration
 | |
| 	MBPerS            float64 // MB processed per second
 | |
| 	Measured          int     // which measurements were recorded
 | |
| 	Ord               int     // ordinal position within a benchmark run
 | |
| }
 | |
| 
 | |
| // ParseLine extracts a Benchmark from a single line of testing.B
 | |
| // output.
 | |
| func ParseLine(line string) (*Benchmark, error) {
 | |
| 	fields := strings.Fields(line)
 | |
| 
 | |
| 	// Two required, positional fields: Name and iterations.
 | |
| 	if len(fields) < 2 {
 | |
| 		return nil, fmt.Errorf("two fields required, have %d", len(fields))
 | |
| 	}
 | |
| 	if !strings.HasPrefix(fields[0], "Benchmark") {
 | |
| 		return nil, fmt.Errorf(`first field does not start with "Benchmark"`)
 | |
| 	}
 | |
| 	n, err := strconv.Atoi(fields[1])
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	b := &Benchmark{Name: fields[0], N: n}
 | |
| 
 | |
| 	// Parse any remaining pairs of fields; we've parsed one pair already.
 | |
| 	for i := 1; i < len(fields)/2; i++ {
 | |
| 		b.parseMeasurement(fields[i*2], fields[i*2+1])
 | |
| 	}
 | |
| 	return b, nil
 | |
| }
 | |
| 
 | |
| func (b *Benchmark) parseMeasurement(quant string, unit string) {
 | |
| 	switch unit {
 | |
| 	case "ns/op":
 | |
| 		if f, err := strconv.ParseFloat(quant, 64); err == nil {
 | |
| 			b.NsPerOp = f
 | |
| 			b.Measured |= NsPerOp
 | |
| 		}
 | |
| 	case "MB/s":
 | |
| 		if f, err := strconv.ParseFloat(quant, 64); err == nil {
 | |
| 			b.MBPerS = f
 | |
| 			b.Measured |= MBPerS
 | |
| 		}
 | |
| 	case "B/op":
 | |
| 		if i, err := strconv.ParseUint(quant, 10, 64); err == nil {
 | |
| 			b.AllocedBytesPerOp = i
 | |
| 			b.Measured |= AllocedBytesPerOp
 | |
| 		}
 | |
| 	case "allocs/op":
 | |
| 		if i, err := strconv.ParseUint(quant, 10, 64); err == nil {
 | |
| 			b.AllocsPerOp = i
 | |
| 			b.Measured |= AllocsPerOp
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (b *Benchmark) String() string {
 | |
| 	buf := new(bytes.Buffer)
 | |
| 	fmt.Fprintf(buf, "%s %d", b.Name, b.N)
 | |
| 	if (b.Measured & NsPerOp) != 0 {
 | |
| 		fmt.Fprintf(buf, " %.2f ns/op", b.NsPerOp)
 | |
| 	}
 | |
| 	if (b.Measured & MBPerS) != 0 {
 | |
| 		fmt.Fprintf(buf, " %.2f MB/s", b.MBPerS)
 | |
| 	}
 | |
| 	if (b.Measured & AllocedBytesPerOp) != 0 {
 | |
| 		fmt.Fprintf(buf, " %d B/op", b.AllocedBytesPerOp)
 | |
| 	}
 | |
| 	if (b.Measured & AllocsPerOp) != 0 {
 | |
| 		fmt.Fprintf(buf, " %d allocs/op", b.AllocsPerOp)
 | |
| 	}
 | |
| 	return buf.String()
 | |
| }
 | |
| 
 | |
| // Set is a collection of benchmarks from one
 | |
| // testing.B run, keyed by name to facilitate comparison.
 | |
| type Set map[string][]*Benchmark
 | |
| 
 | |
| // ParseSet extracts a Set from testing.B output.
 | |
| // ParseSet preserves the order of benchmarks that have identical
 | |
| // names.
 | |
| func ParseSet(r io.Reader) (Set, error) {
 | |
| 	bb := make(Set)
 | |
| 	scan := bufio.NewScanner(r)
 | |
| 	ord := 0
 | |
| 	for scan.Scan() {
 | |
| 		if b, err := ParseLine(scan.Text()); err == nil {
 | |
| 			b.Ord = ord
 | |
| 			ord++
 | |
| 			bb[b.Name] = append(bb[b.Name], b)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if err := scan.Err(); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return bb, nil
 | |
| }
 |