5

私は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ディレクトリ内のすべてのファイルをgrep調べ、ゴルーチン内の各ファイルに対して a を実行します。したがって、これはディレクトリに存在するファイルの数であるnゴルーチンを生成します。メインは、すべてのゴルーチンが作業を完了するまで待機します。n/tmp

興味深いことに、このプログラムの実行には、ゴルーチンの有無にかかわらず同じ時間がかかります。go grep (path, c)and を実行してみてくださいgrep (path, c)(これを行うときは、チャンネルの内容にコメントする必要があります)。

複数のgrepが同時に実行されるため、ゴルーチンバージョンがより高速に実行されることを期待していました。しかし、ほぼ同じ時間で実行されます。なぜこれが起こるのだろうか?

4

2 に答える 2

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
于 2013-06-27T14:46:30.063 に答える