From 1f631a2f9a20d8dc57fb877fb95f807c895d1c40 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Tue, 13 Jun 2017 13:54:46 +0200 Subject: [PATCH] cmd/go: parallelize fmt Currently go fmt formats all files sequentially. That's a shame. Parallelize it over files. Reduces time of go fmt ./... in std lib from ~6.1s to ~0.9s. Reduces time of go fmt github.com/google/syzkaller/... from ~5.2s to ~1.8s. Change-Id: I3d27fc25326106b2a4781e13506a25c12d5bcdc5 Reviewed-on: https://go-review.googlesource.com/45491 Run-TryBot: Dmitry Vyukov Reviewed-by: Ian Lance Taylor --- src/cmd/go/internal/fmtcmd/fmt.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/cmd/go/internal/fmtcmd/fmt.go b/src/cmd/go/internal/fmtcmd/fmt.go index 0563a0410b377..5839028b07da5 100644 --- a/src/cmd/go/internal/fmtcmd/fmt.go +++ b/src/cmd/go/internal/fmtcmd/fmt.go @@ -8,6 +8,8 @@ package fmtcmd import ( "os" "path/filepath" + "runtime" + "sync" "cmd/go/internal/base" "cmd/go/internal/cfg" @@ -41,13 +43,29 @@ See also: go fix, go vet. func runFmt(cmd *base.Command, args []string) { gofmt := gofmtPath() + procs := runtime.GOMAXPROCS(0) + var wg sync.WaitGroup + wg.Add(procs) + fileC := make(chan string, 2*procs) + for i := 0; i < procs; i++ { + go func() { + defer wg.Done() + for file := range fileC { + base.Run(str.StringList(gofmt, "-l", "-w", file)) + } + }() + } for _, pkg := range load.Packages(args) { // Use pkg.gofiles instead of pkg.Dir so that // the command only applies to this package, // not to packages in subdirectories. files := base.FilterDotUnderscoreFiles(base.RelPaths(pkg.Internal.AllGoFiles)) - base.Run(str.StringList(gofmt, "-l", "-w", files)) + for _, file := range files { + fileC <- file + } } + close(fileC) + wg.Wait() } func gofmtPath() string {