diff options
author | Albert Nigmatzianov <albertnigma@gmail.com> | 2016-11-19 00:06:54 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2016-11-19 00:06:54 +0100 |
commit | 29fda0e6830cd62667fb2e12627b8b9874bfafdf (patch) | |
tree | c2e72dad36d9316d9999e4be7ce9b797c23bb50b /commands | |
parent | 7b8a09d5f95391877e3fcee7f1b0e4648050f30f (diff) |
commands: Make benchmark command more useful
* Add information about average time, memory consumption and
allocations.
* Fix situation, when user provides memprofile and cpuprofile, but
cpuprofile will not created.
Fixes #2432
Diffstat (limited to 'commands')
-rw-r--r-- | commands/benchmark.go | 73 |
1 files changed, 48 insertions, 25 deletions
diff --git a/commands/benchmark.go b/commands/benchmark.go index b24d06ff4..ff982684a 100644 --- a/commands/benchmark.go +++ b/commands/benchmark.go @@ -15,15 +15,18 @@ package commands import ( "os" + "runtime" "runtime/pprof" + "time" "github.com/spf13/cobra" + jww "github.com/spf13/jwalterweatherman" ) var ( benchmarkTimes int - cpuProfilefile string - memProfilefile string + cpuProfileFile string + memProfileFile string ) var benchmarkCmd = &cobra.Command{ @@ -37,48 +40,68 @@ func init() { initHugoBuilderFlags(benchmarkCmd) initBenchmarkBuildingFlags(benchmarkCmd) - benchmarkCmd.Flags().StringVar(&cpuProfilefile, "cpuprofile", "", "path/filename for the CPU profile file") - benchmarkCmd.Flags().StringVar(&memProfilefile, "memprofile", "", "path/filename for the memory profile file") - + benchmarkCmd.Flags().StringVar(&cpuProfileFile, "cpuprofile", "", "path/filename for the CPU profile file") + benchmarkCmd.Flags().StringVar(&memProfileFile, "memprofile", "", "path/filename for the memory profile file") benchmarkCmd.Flags().IntVarP(&benchmarkTimes, "count", "n", 13, "number of times to build the site") benchmarkCmd.RunE = benchmark } func benchmark(cmd *cobra.Command, args []string) error { - if err := InitializeConfig(benchmarkCmd); err != nil { + var err error + if err = InitializeConfig(benchmarkCmd); err != nil { return err } - if memProfilefile != "" { - f, err := os.Create(memProfilefile) - + var memProf *os.File + if memProfileFile != "" { + memProf, err = os.Create(memProfileFile) if err != nil { return err } - for i := 0; i < benchmarkTimes; i++ { - _ = resetAndbuildSites(false) - } - pprof.WriteHeapProfile(f) - f.Close() - - } else { - if cpuProfilefile == "" { - cpuProfilefile = "/tmp/hugo-cpuprofile" - } - f, err := os.Create(cpuProfilefile) + } + var cpuProf *os.File + if cpuProfileFile != "" { + cpuProf, err = os.Create(cpuProfileFile) if err != nil { return err } + } + + var memStats runtime.MemStats + runtime.ReadMemStats(&memStats) + memAllocated := memStats.TotalAlloc + mallocs := memStats.Mallocs + if cpuProf != nil { + pprof.StartCPUProfile(cpuProf) + } - pprof.StartCPUProfile(f) - defer pprof.StopCPUProfile() - for i := 0; i < benchmarkTimes; i++ { - _ = resetAndbuildSites(false) + t := time.Now() + for i := 0; i < benchmarkTimes; i++ { + if err = resetAndbuildSites(false); err != nil { + return err } } + totalTime := time.Since(t) - return nil + if memProf != nil { + pprof.WriteHeapProfile(memProf) + memProf.Close() + } + if cpuProf != nil { + pprof.StopCPUProfile() + cpuProf.Close() + } + + runtime.ReadMemStats(&memStats) + totalMemAllocated := memStats.TotalAlloc - memAllocated + totalMallocs := memStats.Mallocs - mallocs + jww.FEEDBACK.Println() + jww.FEEDBACK.Printf("Average time per operation: %vms\n", int(1000*totalTime.Seconds()/float64(benchmarkTimes))) + jww.FEEDBACK.Printf("Average memory allocated per operation: %vkB\n", totalMemAllocated/uint64(benchmarkTimes)/1024) + jww.FEEDBACK.Printf("Average allocations per operation: %v\n", totalMallocs/uint64(benchmarkTimes)) + + return nil } |