fastwalk
Golang向けの高速並列ディレクトリトラバーサル。
パッケージfastwalkは、filepath.WalkDirの高速並列版を提供し、
macOSで約2.5倍、Linuxで約4倍、Windowsで約6倍高速で、
メモリ使用量は50%削減し、メモリアロケーションも25%少なくなっています。
さらに、OSを問わずgodirwalkより約4~5倍高速です。
golang.org/x/tools/internal/fastwalk(https://pkg.go.dev/golang.org/x/tools@v0.1.9/internal/fastwalk)に触発され、そこから派生しています。
特徴
- 高速:複数のゴルーチンがファイルシステムのstatを行い、
filepath.WalkDirFuncのコールバックを並行して呼び出します - 安全なシンボリックリンクのトラバーサル(
Config.Follow) filepath.WalkDirと同じ動作およびコールバックシグネチャ- 重複ファイルやディレクトリを無視するラッパー関数を提供:
IgnoreDuplicateFiles()
および
IgnoreDuplicateDirs()
- macOS、Linux、Windowsで広範にテスト済み
使い方
使い方はfilepath.WalkDirと同じですが、
fastwalk.WalkのwalkFn引数は並行使用に安全である必要があります。
サンプルはexamplesディレクトリにあります。
以下の例は、POSIXの非常に簡単なバージョンの findユーティリティです:
// fwfind is a an example program that is similar to POSIX find, // but faster and worse (it's an example). package mainimport ( "flag" "fmt" "io/fs" "os" "path/filepath"
"github.com/charlievieth/fastwalk" )
const usageMsg =
Usage: %[1]s [-L] [-name] [PATH...]:%[1]s is a poor replacement for the POSIX find utility
func main() { flag.Usage = func() { fmt.Fprintf(os.Stdout, usageMsg, filepath.Base(os.Args[0])) flag.PrintDefaults() } pattern := flag.String("name", "", "Pattern to match file names against.") followLinks := flag.Bool("L", false, "Follow symbolic links") flag.Parse()
// If no paths are provided default to the current directory: "." args := flag.Args() if len(args) == 0 { args = append(args, ".") }
// Follow links if the "-L" flag is provided conf := fastwalk.Config{ Follow: *followLinks, }
walkFn := func(path string, d fs.DirEntry, err error) error { if err != nil { fmt.Fprintf(os.Stderr, "%s: %v\n", path, err) return nil // returning the error stops iteration } if *pattern != "" { if ok, err := filepath.Match(*pattern, d.Name()); !ok { // invalid pattern (err != nil) or name does not match return err } } _, err = fmt.Println(path) return err } for _, root := range args { if err := fastwalk.Walk(&conf, root, walkFn); err != nil { fmt.Fprintf(os.Stderr, "%s: %v\n", root, err) os.Exit(1) } } }
ベンチマーク
ベンチマークは go1.17.6 を使用して作成されており、bench_comp メイクターゲットで生成できます:
$ make bench_compダーウィン
ハードウェア:
goos: darwin
goarch: arm64
cpu: Apple M1 Max#### filepath.WalkDir と fastwalk.Walk() の比較:
filepath fastwalk delta
time/op 27.9ms ± 1% 13.0ms ± 1% -53.33%
alloc/op 4.33MB ± 0% 2.14MB ± 0% -50.55%
allocs/op 50.9k ± 0% 37.7k ± 0% -26.01%#### godirwalk.Walk() と fastwalk.Walk():
godirwalk fastwalk delta
time/op 58.5ms ± 3% 18.0ms ± 2% -69.30%
alloc/op 25.3MB ± 0% 2.1MB ± 0% -91.55%
allocs/op 57.6k ± 0% 37.7k ± 0% -34.59%Linux
ハードウェア:
goos: linux
goarch: amd64
cpu: Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
drive: Samsung SSD 970 PRO 1TB#### filepath.WalkDir と fastwalk.Walk() の比較:
filepath fastwalk delta
time/op 10.1ms ± 2% 2.8ms ± 2% -72.83%
alloc/op 2.44MB ± 0% 1.70MB ± 0% -30.46%
allocs/op 47.2k ± 0% 36.9k ± 0% -21.80%#### godirwalk.Walk() と fastwalk.Walk() の比較:
filepath fastwalk delta
time/op 13.7ms ±16% 2.8ms ± 2% -79.88%
alloc/op 7.48MB ± 0% 1.70MB ± 0% -77.34%
allocs/op 53.8k ± 0% 36.9k ± 0% -31.38%Windows
ハードウェア:
goos: windows
goarch: amd64
pkg: github.com/charlievieth/fastwalk
cpu: Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz#### filepath.WalkDir と fastwalk.Walk() の比較:
filepath fastwalk delta
time/op 88.0ms ± 1% 14.6ms ± 1% -83.47%
alloc/op 5.68MB ± 0% 6.76MB ± 0% +19.01%
allocs/op 69.6k ± 0% 90.4k ± 0% +29.87%#### godirwalk.Walk() と fastwalk.Walk():
filepath fastwalk delta
time/op 87.4ms ± 1% 14.6ms ± 1% -83.34%
alloc/op 6.14MB ± 0% 6.76MB ± 0% +10.24%
allocs/op 100k ± 0% 90k ± 0% -9.59%--- Tranlated By Open Ai Tx | Last indexed: 2026-05-17 ---