| // 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()) | |
| } |