我正在学习Go编程语言。请考虑以下计划,
package main
import (
"fmt"
"bytes"
"os"
"os/exec"
"path/filepath"
"sync"
)
func grep(file string) {
defer wg.Done()
cmd := exec.Command("grep", "-H", "--color=always", "add", file)
var out bytes.Buffer
cmd.Stdout = &out
cmd.Run()
fmt.Printf("%s\n", out.String())
}
func walkFn(path string, info os.FileInfo, err error) error {
if !info.IsDir() {
wg.Add(1)
go grep (path)
}
return nil
}
var wg sync.WaitGroup
func main() {
filepath.Walk("/tmp/", walkFn)
wg.Wait()
}
此程序遍历/tmp
目录中的所有文件,并对goroutine中的每个文件执行grep
。因此,这将生成n
goroutines,其中n
是/tmp
目录中存在的文件数。主要等到所有goroutines完成工作。
有趣的是,这个程序需要花费相同的时间来执行和不使用goroutines。尝试运行go grep (path, c)
和grep (path, c)
(您需要在执行此操作时评论频道内容)。
我期待goroutine版本在多个grep同时运行时运行得更快。但它几乎在同等时间内执行。我想知道为什么会这样?
答案 0 :(得分:6)
尝试使用更多内核。此外,使用更好的根目录进行比较,例如Go目录。 SSD也有很大的不同。例如,
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
goroot := "/home/peter/go/"
filepath.Walk(goroot, walkFn)
wg.Wait()
fmt.Println("GOMAXPROCS:", runtime.GOMAXPROCS(0))
}
GOMAXPROCS: 1
real 0m10.137s
user 0m2.628s
sys 0m6.472s
GOMAXPROCS: 4
real 0m3.284s
user 0m2.492s
sys 0m5.116s
答案 1 :(得分:4)
你的程序的性能与磁盘的速度有关(或ram,如果/ tmp是ram磁盘):计算是I/O bound。无论有多少goroutine并行运行,它都读得不快。