本文共 1690 字,大约阅读时间需要 5 分钟。
查找 dir 目录下文件名中包含 dst 字符串的文件个数,遇到目录则递归遍历。
最直接的方法:package mainimport ( "fmt" "io/ioutil" "strings" "time")var dst = "main"var dir = "D:/dev"var c = 0// 查找目录树func main() { main1()}func main1() { start := time.Now() search1(dir) fmt.Println(c) use := time.Since(start) fmt.Println(use)}func search1(dir string) { fs, err := ioutil.ReadDir(dir) if err != nil { panic(err) } for _, f := range fs { if f.IsDir() { search1(dir + "/" + f.Name()) } else { if strings.Contains(f.Name(), dst) { c++ } } }}
耗时 30 s
找出 1562 个结果采用 goroutine 优化后
package mainimport ( "fmt" "io/ioutil" "strings" "time")var dst = "main"var dir = "D:/dev"var c = 0// 查找目录树func main() { main3()}var gorCount = 0var maxGorCount = 30var haveResult = make(chan bool)var gorDone = make(chan bool)var gorStart = make(chan string)func main3() { start := time.Now() gorCount = 1 go search3(dir, true) waitGor() fmt.Println(c) use := time.Since(start) fmt.Println(use)}func waitGor() { for { select { case <-gorDone: gorCount-- if gorCount == 0 { return } case dirname := <-gorStart: gorCount++ go search3(dirname, true) case <-haveResult: c++ } }}func search3(dir string, gor bool) { fs, err := ioutil.ReadDir(dir) if err == nil { for _, f := range fs { if f.IsDir() { if gorCount >= maxGorCount { search3(dir+"/"+f.Name(), false) } else { gorStart <- dir + "/" + f.Name() } } else { if strings.Contains(f.Name(), dst) { haveResult <- true } } } } else { fmt.Println(err) } if gor { gorDone <- true }}
耗时为 4s,想你提升 7 倍左右
转载地址:http://pnaui.baihongyu.com/