summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-03 10:10:50 +0200
committerPaul Buetow <paul@buetow.org>2026-03-03 10:10:50 +0200
commit778706798fc66b9aa6be739517bb1486b3653e58 (patch)
treed1451bf6f28c58b9e2f3942aa6ea853bdd7cfde0
parentee86322f832ab13bf6aa165a2f6eec8c1ae7772d (diff)
Add benchmark profiling mage targets
-rw-r--r--.gitignore1
-rw-r--r--Magefile.go64
2 files changed, 65 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 6f651c1..86a6136 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@ perltidy.ERR
*.collapsed
*.collapsed.zst
*.svg
+/bench-profiles/
/.cursor/
REVIEW-COMMENTS.md
/.serena/
diff --git a/Magefile.go b/Magefile.go
index 09b219c..e2f5b69 100644
--- a/Magefile.go
+++ b/Magefile.go
@@ -40,6 +40,7 @@ const (
typesGoPath = "internal/types/generated_types.go"
typesHeaderPath = "internal/c/types.h"
VMLINUXPath = "internal/c/vmlinux.h"
+ benchProfilesDir = "bench-profiles"
integrationParallel = "INTEGRATION_PARALLEL"
integrationParallelE = "IOR_INTEGRATION_PARALLEL"
)
@@ -126,6 +127,58 @@ func Bench() error {
return sh.RunWithV(goEnv(), "go", "test", "./...", "-v", "-bench=.", "-run", "xxx")
}
+// BenchProf runs pipeline benchmarks and writes timestamped pprof artifacts.
+func BenchProf() error {
+ if err := ensureBenchProfilesDir(); err != nil {
+ return err
+ }
+
+ timestamp := benchTimestamp()
+ cpuProfile := filepath.Join(benchProfilesDir, fmt.Sprintf("pipeline-%s-cpu.prof", timestamp))
+ memProfile := filepath.Join(benchProfilesDir, fmt.Sprintf("pipeline-%s-mem.prof", timestamp))
+ blockProfile := filepath.Join(benchProfilesDir, fmt.Sprintf("pipeline-%s-block.prof", timestamp))
+
+ if err := sh.RunWithV(goEnv(), "go", "test", "./internal",
+ "-run", "^$",
+ "-bench", "^BenchmarkPipeline",
+ "-benchmem",
+ "-count=1",
+ "-cpuprofile", cpuProfile,
+ "-memprofile", memProfile,
+ "-blockprofile", blockProfile,
+ ); err != nil {
+ return err
+ }
+
+ fmt.Println("Profiles written:")
+ fmt.Println(" ", cpuProfile)
+ fmt.Println(" ", memProfile)
+ fmt.Println(" ", blockProfile)
+ fmt.Println("Analyze with:")
+ fmt.Printf(" go tool pprof -http=:8080 %s\n", cpuProfile)
+ fmt.Printf(" go tool pprof -http=:8080 %s\n", memProfile)
+ fmt.Printf(" go tool pprof -http=:8080 %s\n", blockProfile)
+ return nil
+}
+
+// BenchCompare runs all benchmarks repeatedly and stores output for benchstat.
+func BenchCompare() error {
+ if err := ensureBenchProfilesDir(); err != nil {
+ return err
+ }
+
+ outputFile := filepath.Join(benchProfilesDir, fmt.Sprintf("bench-%s.txt", benchTimestamp()))
+ cmd := fmt.Sprintf("go test ./... -v -bench=. -run=xxx -benchmem -count=6 | tee %q", outputFile)
+ if err := sh.RunWithV(goEnv(), "sh", "-c", cmd); err != nil {
+ return err
+ }
+
+ fmt.Println("Bench output written to:", outputFile)
+ fmt.Println("Compare snapshots with:")
+ fmt.Println(" benchstat bench-profiles/bench-*.txt")
+ return nil
+}
+
// Generate regenerates all generated files.
func Generate() error {
fmt.Println("Generating tracepoint and type artifacts...")
@@ -377,6 +430,17 @@ func bpfEnv() map[string]string {
return map[string]string{"CC": "clang"}
}
+func ensureBenchProfilesDir() error {
+ if err := os.MkdirAll(benchProfilesDir, 0o755); err != nil {
+ return fmt.Errorf("ensure %s: %w", benchProfilesDir, err)
+ }
+ return nil
+}
+
+func benchTimestamp() string {
+ return time.Now().UTC().Format("20060102-150405")
+}
+
func cleanBPFArtifacts() error {
for _, pattern := range []string{"internal/c/*.o", VMLINUXPath} {
if err := removeFilesByGlob(pattern); err != nil {