golang遍历目录树性能对比

查找 dir 目录下文件名中包含 dst 字符串的文件个数,遇到目录则递归遍历。
最直接的方法:

package main

import (
   "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 main

import (
	"fmt"
	"io/ioutil"
	"strings"
	"time"
)

var dst = "main"
var dir = "D:/dev"
var c = 0

// 查找目录树
func main() {
	main3()
}

var gorCount = 0
var maxGorCount = 30
var 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 倍左右

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值