diff options
Diffstat (limited to 'dependencies/pkg/mod/go.uber.org/zap@v1.23.0/internal/readme')
-rw-r--r-- | dependencies/pkg/mod/go.uber.org/zap@v1.23.0/internal/readme/readme.go | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/dependencies/pkg/mod/go.uber.org/zap@v1.23.0/internal/readme/readme.go b/dependencies/pkg/mod/go.uber.org/zap@v1.23.0/internal/readme/readme.go new file mode 100644 index 0000000..54c74af --- /dev/null +++ b/dependencies/pkg/mod/go.uber.org/zap@v1.23.0/internal/readme/readme.go @@ -0,0 +1,242 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package main + +import ( + "flag" + "fmt" + "io" + "log" + "os" + "os/exec" + "sort" + "strconv" + "strings" + "text/template" + "time" +) + +var ( + libraryNameToMarkdownName = map[string]string{ + "Zap": ":zap: zap", + "Zap.Sugar": ":zap: zap (sugared)", + "stdlib.Println": "standard library", + "sirupsen/logrus": "logrus", + "go-kit/kit/log": "go-kit", + "inconshreveable/log15": "log15", + "apex/log": "apex/log", + "rs/zerolog": "zerolog", + } +) + +func main() { + flag.Parse() + if err := do(); err != nil { + log.Fatal(err) + } +} + +func do() error { + tmplData, err := getTmplData() + if err != nil { + return err + } + data, err := io.ReadAll(os.Stdin) + if err != nil { + return err + } + t, err := template.New("tmpl").Parse(string(data)) + if err != nil { + return err + } + return t.Execute(os.Stdout, tmplData) +} + +func getTmplData() (*tmplData, error) { + tmplData := &tmplData{} + rows, err := getBenchmarkRows("BenchmarkAddingFields") + if err != nil { + return nil, err + } + tmplData.BenchmarkAddingFields = rows + rows, err = getBenchmarkRows("BenchmarkAccumulatedContext") + if err != nil { + return nil, err + } + tmplData.BenchmarkAccumulatedContext = rows + rows, err = getBenchmarkRows("BenchmarkWithoutFields") + if err != nil { + return nil, err + } + tmplData.BenchmarkWithoutFields = rows + return tmplData, nil +} + +func getBenchmarkRows(benchmarkName string) (string, error) { + benchmarkOutput, err := getBenchmarkOutput(benchmarkName) + if err != nil { + return "", err + } + + // get the Zap time (unsugared) as baseline to compare with other loggers + baseline, err := getBenchmarkRow(benchmarkOutput, benchmarkName, "Zap", nil) + if err != nil { + return "", err + } + + var benchmarkRows []*benchmarkRow + for libraryName := range libraryNameToMarkdownName { + benchmarkRow, err := getBenchmarkRow( + benchmarkOutput, benchmarkName, libraryName, baseline, + ) + if err != nil { + return "", err + } + if benchmarkRow == nil { + continue + } + benchmarkRows = append(benchmarkRows, benchmarkRow) + } + sort.Sort(benchmarkRowsByTime(benchmarkRows)) + rows := []string{ + "| Package | Time | Time % to zap | Objects Allocated |", + "| :------ | :--: | :-----------: | :---------------: |", + } + for _, benchmarkRow := range benchmarkRows { + rows = append(rows, benchmarkRow.String()) + } + return strings.Join(rows, "\n"), nil +} + +func getBenchmarkRow( + input []string, benchmarkName string, libraryName string, baseline *benchmarkRow, +) (*benchmarkRow, error) { + line, err := findUniqueSubstring(input, fmt.Sprintf("%s/%s-", benchmarkName, libraryName)) + if err != nil { + return nil, err + } + if line == "" { + return nil, nil + } + split := strings.Split(line, "\t") + if len(split) < 5 { + return nil, fmt.Errorf("unknown benchmark line: %s", line) + } + duration, err := time.ParseDuration(strings.Replace(strings.TrimSuffix(strings.TrimSpace(split[2]), "/op"), " ", "", -1)) + if err != nil { + return nil, err + } + allocatedBytes, err := strconv.Atoi(strings.TrimSuffix(strings.TrimSpace(split[3]), " B/op")) + if err != nil { + return nil, err + } + allocatedObjects, err := strconv.Atoi(strings.TrimSuffix(strings.TrimSpace(split[4]), " allocs/op")) + if err != nil { + return nil, err + } + r := &benchmarkRow{ + Name: libraryNameToMarkdownName[libraryName], + Time: duration, + AllocatedBytes: allocatedBytes, + AllocatedObjects: allocatedObjects, + } + + if baseline != nil { + r.ZapTime = baseline.Time + r.ZapAllocatedBytes = baseline.AllocatedBytes + r.ZapAllocatedObjects = baseline.AllocatedObjects + } + + return r, nil +} + +func findUniqueSubstring(input []string, substring string) (string, error) { + var output string + for _, line := range input { + if strings.Contains(line, substring) { + if output != "" { + return "", fmt.Errorf("input has duplicate substring %s", substring) + } + output = line + } + } + return output, nil +} + +func getBenchmarkOutput(benchmarkName string) ([]string, error) { + cmd := exec.Command("go", "test", fmt.Sprintf("-bench=%s", benchmarkName), "-benchmem") + cmd.Dir = "benchmarks" + output, err := cmd.CombinedOutput() + if err != nil { + return nil, fmt.Errorf("error running 'go test -bench=%q': %v\n%s", benchmarkName, err, string(output)) + } + return strings.Split(string(output), "\n"), nil +} + +type tmplData struct { + BenchmarkAddingFields string + BenchmarkAccumulatedContext string + BenchmarkWithoutFields string +} + +type benchmarkRow struct { + Name string + + Time time.Duration + AllocatedBytes int + AllocatedObjects int + + ZapTime time.Duration + ZapAllocatedBytes int + ZapAllocatedObjects int +} + +func (b *benchmarkRow) String() string { + pct := func(val, baseline int64) string { + return fmt.Sprintf( + "%+0.f%%", + ((float64(val)/float64(baseline))*100)-100, + ) + } + t := b.Time.Nanoseconds() + tp := pct(t, b.ZapTime.Nanoseconds()) + + return fmt.Sprintf( + "| %s | %d ns/op | %s | %d allocs/op", b.Name, + t, tp, b.AllocatedObjects, + ) +} + +type benchmarkRowsByTime []*benchmarkRow + +func (b benchmarkRowsByTime) Len() int { return len(b) } +func (b benchmarkRowsByTime) Swap(i, j int) { b[i], b[j] = b[j], b[i] } +func (b benchmarkRowsByTime) Less(i, j int) bool { + left, right := b[i], b[j] + leftZap, rightZap := strings.Contains(left.Name, "zap"), strings.Contains(right.Name, "zap") + + // If neither benchmark is for zap or both are, sort by time. + if leftZap == rightZap { + return left.Time.Nanoseconds() < right.Time.Nanoseconds() + } + // Sort zap benchmark first. + return leftZap +} |