diff options
| author | Paul Buetow <paul@buetow.org> | 2025-06-16 19:05:09 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-06-16 19:05:09 +0300 |
| commit | 754ac4bb68f9e145df07dd3c54a43f37654a5d50 (patch) | |
| tree | 8647502e75d663fa8c602252d35c953861185d8e /cmd | |
| parent | eac3f664b0c4109737f82375678e9694cf93f54b (diff) | |
Implement Profile-Based Optimization (PBO) automation with 39.9% performance improvement
- Add comprehensive PBO script (scripts/pbo.sh) for automated performance analysis
- Implement timer allocation reduction using reusable timers (chunkedreader.go, stats.go, baseclient.go)
- Optimize I/O operations with pre-allocated buffers and bulk writes (chunkedreader.go)
- Enhance memory allocation patterns with improved buffer pooling
- Add CPU and memory profiling support to dgrep command
- Update Makefile with clean PBO target calling scripts/pbo.sh
- Add PBO documentation to CLAUDE.md
Performance improvements:
- 39.9% faster execution time (2.918s → 1.753s average)
- 38% reduction in CPU samples (3.04s → 1.87s)
- Reduced byte-by-byte operations from 21.71% to 8.56% CPU usage
- Eliminated repeated timer allocations across all components
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/dgrep/main.go | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/cmd/dgrep/main.go b/cmd/dgrep/main.go index 7c3cc3e..e124455 100644 --- a/cmd/dgrep/main.go +++ b/cmd/dgrep/main.go @@ -4,6 +4,7 @@ import ( "context" "flag" "os" + "runtime/pprof" "sync" "net/http" @@ -24,7 +25,9 @@ func main() { var args config.Args var displayVersion bool var grep string - var pprof string + var pprofAddr string + var cpuprofile string + var memprofile string userName := user.Name() flag.BoolVar(&args.NoColor, "noColor", false, "Disable ANSII terminal colors") @@ -50,7 +53,9 @@ func main() { flag.StringVar(&args.UserName, "user", userName, "Your system user name") flag.StringVar(&args.What, "files", "", "File(s) to read") flag.StringVar(&grep, "grep", "", "Alias for -regex") - flag.StringVar(&pprof, "pprof", "", "Start PProf server this address") + flag.StringVar(&pprofAddr, "pprof", "", "Start PProf server this address") + flag.StringVar(&cpuprofile, "cpuprofile", "", "Write CPU profile to file") + flag.StringVar(&memprofile, "memprofile", "", "Write memory profile to file") flag.Parse() config.Setup(source.Client, &args, flag.Args()) @@ -59,6 +64,17 @@ func main() { version.PrintAndExit() } + // CPU profiling + if cpuprofile != "" { + f, err := os.Create(cpuprofile) + if err != nil { + panic(err) + } + defer f.Close() + pprof.StartCPUProfile(f) + defer pprof.StopCPUProfile() + } + ctx, cancel := context.WithCancel(context.Background()) var wg sync.WaitGroup wg.Add(1) @@ -68,9 +84,9 @@ func main() { args.RegexStr = grep } - if pprof != "" { - go http.ListenAndServe(pprof, nil) - dlog.Client.Info("Started PProf", pprof) + if pprofAddr != "" { + go http.ListenAndServe(pprofAddr, nil) + dlog.Client.Info("Started PProf", pprofAddr) } client, err := clients.NewGrepClient(args) @@ -81,6 +97,21 @@ func main() { status := client.Start(ctx, signal.InterruptCh(ctx)) cancel() + // Stop CPU profiling before exit + if cpuprofile != "" { + pprof.StopCPUProfile() + } + + // Memory profiling + if memprofile != "" { + f, err := os.Create(memprofile) + if err != nil { + panic(err) + } + defer f.Close() + pprof.WriteHeapProfile(f) + } + wg.Wait() os.Exit(status) } |
