ErrGroup和WaitGroup性能测试对比
var wg sync.WaitGroup
type Result struct {
path string
data [md5.Size]byte
}
func md5AllByWaitGroup(root string) (map[string][md5.Size]byte,error) {
ctx,cancel := context.WithCancel(context.Background())
defer cancel()
paths := make(chan string)
wg.Add(1)
go getPath(paths,root,ctx)
ret := make(chan Result)
for i :=0;i<20;i++{
wg.Add(1)
go func(paths chan string,ret chan Result) {
defer wg.Done()
for path := range paths{
data,err := ioutil.ReadFile(path)
if err !=nil{
return
}
select {
case ret <- Result{path: path,data: md5.Sum(data)}:
case <-ctx.Done():
return
}
}
}(paths,ret)
}
go func() {
wg.Wait()
close(ret)
}()
m1 := make(map[string][md5.Size]byte)
for v := range ret{
m1[v.path] = v.data
}
return m1,nil
}
func getPath(paths chan string,root string,ctx context.Context) {
defer wg.Done()
defer close(paths)
filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err !=nil{
return err
}
if !info.Mode().IsRegular(){
return nil
}
select {
case paths<- path:
case <-ctx.Done():
return ctx.Err()
}
return nil
})
}
func WaitGroupDemo() {
m,err := md5AllByWaitGroup(".")
if err !=nil{
log.Fatal(err)
}
for k,sum := range m{
fmt.Printf("%s:\t %x\n",k,sum)
}
}
以上使用WaitGroup 实现
执行方式

结果:

func md5AllByErrGroup(ctx context.Context,root string) (map[string][md5.Size]byte,error) {
g,ctx := errgroup.WithContext(ctx)
paths := make(chan string)
g.Go(func() error {
defer close(paths)
return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err !=nil{
return err
}
if !info.Mode().IsRegular(){
return nil
}
select {
case paths <-path:
case <-ctx.Done():
return ctx.Err()
}
return nil
})
})
c :=make(chan Result)
for i:=0;i<20;i++{
g.Go(func() error {
for path := range paths{
data,err := ioutil.ReadFile(path)
if err !=nil{
return err
}
select {
case c <- Result{path: path,data: md5.Sum(data)}:
case <-ctx.Done():
return ctx.Err()
}
}
return nil
})
}
go func() {
g.Wait()
close(c)
}()
m := make(map[string][md5.Size]byte)
for v := range c{
m[v.path] = v.data
}
if err := g.Wait();err !=nil{
return nil,err
}
return m,nil
}
func ErrGroupDemo() {
m,err := md5AllByErrGroup(context.Background(),".")
if err !=nil{
log.Fatal(err)
}
for k,sum := range m{
fmt.Printf("%s:\t %x\n",k,sum)
}
}
以上是ErrGroup 实现,
执行方式

结果


浙公网安备 33010602011771号