| // Copyright 2026 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 stats provides a convenient way to collect compiler statistics. |
| package stats |
| |
| import ( |
| "fmt" |
| "log" |
| "sort" |
| "strings" |
| ) |
| |
| type Stats struct { |
| stats []*PrefixStats |
| } |
| |
| func (s *Stats) Merge(other *Stats) { |
| if s == nil || other == nil { |
| return |
| } |
| allKeys := map[string]struct{}{} |
| for _, s := range s.stats { |
| allKeys[s.prefix] = struct{}{} |
| } |
| for _, s := range other.stats { |
| allKeys[s.prefix] = struct{}{} |
| } |
| newStats := []*PrefixStats{} |
| for k := range allKeys { |
| newS := &PrefixStats{prefix: k, stats: make(map[string]int64)} |
| for _, s1 := range s.stats { |
| if s1.prefix == k { |
| newS.Merge(s1) |
| } |
| } |
| for _, s2 := range other.stats { |
| if s2.prefix == k { |
| newS.Merge(s2) |
| } |
| } |
| newStats = append(newStats, newS) |
| } |
| s.stats = newStats |
| } |
| |
| func (s *Stats) Print() { |
| if s == nil { |
| return |
| } |
| for _, s := range s.stats { |
| s.Print() |
| } |
| } |
| |
| func (s *Stats) NewPrefixStat(p string) *PrefixStats { |
| if s == nil { |
| return nil |
| } |
| pstat := &PrefixStats{prefix: p, stats: make(map[string]int64)} |
| s.stats = append(s.stats, pstat) |
| return pstat |
| } |
| |
| // Stats holds a collection of statistics. |
| type PrefixStats struct { |
| prefix string |
| stats map[string]int64 |
| } |
| |
| // Record records a value for a given statistic. |
| func (s *PrefixStats) Record(name string, value int64) { |
| if s == nil { |
| return |
| } |
| s.stats[name] += value |
| } |
| |
| // Merge merges another Stats object into this one. |
| func (s *PrefixStats) Merge(other *PrefixStats) { |
| if s == nil || other == nil { |
| return |
| } |
| for name, value := range other.stats { |
| s.stats[name] += value |
| } |
| } |
| |
| // Print prints the collected statistics to the console. |
| func (s *PrefixStats) Print() { |
| if s == nil { |
| return |
| } |
| var names []string |
| for name := range s.stats { |
| names = append(names, name) |
| } |
| sort.Strings(names) |
| |
| var b strings.Builder |
| fmt.Fprintln(&b, "Compiler statistics:") |
| for _, name := range names { |
| fmt.Fprintf(&b, "%s-%-30s: %d\n", s.prefix, name, s.stats[name]) |
| } |
| log.Print(b.String()) |
| } |