为什么这个程序在使用goroutines时表现不佳?

Nav*_*K N 5 concurrency performance grep go

我正在学习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()
}
Run Code Online (Sandbox Code Playgroud)

该程序遍历目录中的所有文件/tmp,并grep在goroutine中的每个文件上执行.所以这将产生ngoroutines,其中n是目录中存在的文件数/tmp.主要等到所有goroutines完成工作.

有趣的是,这个程序需要相同的时间来执行有和没有goroutines.尝试运行go grep (path, c)grep (path, c)(在执行此操作时需要评论频道内容).

我期待goroutine版本运行得更快,因为多个grep同时运行.但它几乎在同等时间内执行.我想知道为什么会这样?

pet*_*rSO 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
Run Code Online (Sandbox Code Playgroud)