いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-422 (filepath.Walkとfilepath.WalkDirの処理速度の違い)

関連記事

GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ

概要

以下、自分用のメモです。忘れない内にメモメモ。。。

filepath.Walk の説明に以下のように記載されていました。

Walk is less efficient than WalkDir, introduced in Go 1.16, which avoids calling os.Lstat on every visited file or directory.

filepath.Walk が最初から存在しているAPI。filepath.WalkDir が Go 1.16 で追加されたももの。

filepath.Walk は、訪問したリソースに対して os.Lstat を呼び出すようになっているため、少し非効率であると記載されています。

実際にベンチマークして算出してみました。

サンプル

package main

import (
    "io/fs"
    "os"
    "path/filepath"
    "testing"
)

const (
    dir = "../../../"
)

func TestMain(m *testing.M) {
    err := os.Chdir(dir)
    if err != nil {
        os.Exit(1)
    }

    ret := m.Run()

    os.Exit(ret)
}

func BenchmarkWalk(b *testing.B) {
    for i := 0; i < b.N; i++ {
        filepath.Walk(".", func(path string, info fs.FileInfo, err error) error {
            return nil
        })
    }
}

func BenchmarkWalkDir(b *testing.B) {
    for i := 0; i < b.N; i++ {
        filepath.WalkDir(".", func(path string, info fs.DirEntry, err error) error {
            return nil
        })
    }
}

実行すると以下のようになります。

$ task
task: [default] go test -count 3 -run '^$' -benchmem -bench .
goos: linux
goarch: amd64
pkg: github.com/devlights/try-golang/examples/singleapp/walk_walkdir_benchmark
cpu: AMD EPYC 7B13
BenchmarkWalk-16             129           8551681 ns/op          629966 B/op       8957 allocs/op
BenchmarkWalk-16             141           8357755 ns/op          630023 B/op       8957 allocs/op
BenchmarkWalk-16             147           8338617 ns/op          630068 B/op       8957 allocs/op
BenchmarkWalkDir-16          237           4763289 ns/op          348053 B/op       8205 allocs/op
BenchmarkWalkDir-16          248           4924557 ns/op          348213 B/op       8205 allocs/op
BenchmarkWalkDir-16          229           5093532 ns/op          348304 B/op       8205 allocs/op
PASS
ok      github.com/devlights/try-golang/examples/singleapp/walk_walkdir_benchmark       11.160s

確かに filepath.WalkDir の方が処理速度が速く、メモリ割り当ても効率的ですね。

参考情報

Goのおすすめ書籍


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。