From b36bbf080029df0059ba84dd388a7ea036f3b64a Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Fri, 4 Sep 2026 00:50:17 +0200 Subject: [PATCH] Parallelize corpus benchmark across cores + disable GC --- benchmark/main.go | 48 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/benchmark/main.go b/benchmark/main.go index 773ea9e..1c8a3ca 100644 --- a/benchmark/main.go +++ b/benchmark/main.go @@ -1,4 +1,5 @@ // Corpus benchmark: parse every .php file under the given path and report timing. +// Parsing runs across GOMAXPROCS workers with the GC disabled for the short-lived run. package main import ( @@ -6,6 +7,10 @@ import ( "io/fs" "os" "path/filepath" + "runtime" + "runtime/debug" + "sync" + "sync/atomic" "time" "github.com/rectorphp/php-parser-in-go/pkg/conf" @@ -26,20 +31,47 @@ func main() { } config := conf.Config{Version: phpVersion} + // short-lived process: parse throughput matters, not steady-state memory + debug.SetGCPercent(-1) + files := collectPHPFiles(root) start := time.Now() + parsed := parseAll(files, config) + elapsed := time.Since(start) + + fmt.Printf("parsed %d files in %d ms\n", parsed, elapsed.Milliseconds()) +} + +// parseAll parses every file across GOMAXPROCS workers and returns the count parsed. +func parseAll(files []string, config conf.Config) int64 { + jobs := make(chan string, runtime.GOMAXPROCS(0)) + var parsed int64 + + var wg sync.WaitGroup + for range runtime.GOMAXPROCS(0) { + wg.Add(1) + go func() { + defer wg.Done() + for path := range jobs { + content, err := os.ReadFile(path) + if err != nil { + continue + } + // broken fixtures return an error; the parse work is what we time + parser.Parse(content, config) + atomic.AddInt64(&parsed, 1) + } + }() + } + for _, path := range files { - content, err := os.ReadFile(path) - if err != nil { - continue - } - // broken fixtures return an error; the parse work is what we time - parser.Parse(content, config) + jobs <- path } - elapsed := time.Since(start) + close(jobs) + wg.Wait() - fmt.Printf("parsed %d files in %d ms\n", len(files), elapsed.Milliseconds()) + return parsed } func collectPHPFiles(root string) []string {