douyue3800 2018-04-30 16:18
浏览 38

使用并发提高搜索效率

I have the two following methods for searching for files with a name pattern (e.g. *.go for finding all go files) under a search path (e.g. /Users/username/Desktop). The first method uses recursion + goroutine, and the second method uses a queue to prevent possible stack overflow problem. From my testing on my own computer Desktop that has 41,233 go files, the first method beats the second method by 4 seconds, which are 18 and 22 seconds, respectively.

I was wondering if there is any better way/parallelism to make the search even more efficient, because I am integrating the search in a desktop app, and I don't want the user sitting there and wait for 30 seconds before seeing any search results.

type FileSearcher struct {
    Contents []MyFile
}

func (fe *FileSearcher) FindFileRecursive(searchPath, namePattern string) (err error) {

    // get absolute path
    if searchPath, err = filepath.Abs(searchPath); err != nil {
        return
    }
    curFileName := filepath.Base(searchPath)
    if matched, err := filepath.Match(namePattern, curFileName); err == nil && matched {
        if foundFile, err := NewFileFromPath(searchPath); err == nil {
            fe.Contents = append(fe.Contents, *foundFile) // found a match
        }
    } else {
        return
    }

    if isDir, _ := utils.IsDirectory(searchPath); isDir {
        if files, err := ioutil.ReadDir(searchPath); err == nil {
            for _, f := range files {
                fPath := filepath.Join(searchPath, f.Name())
                go fe.FindFileRecursive(fPath, namePattern) // recursive in a goroutine here
            }
        }
    }
    return
}

// FindFile searches for files/directories matching namePattern under searchPath
func (fe *FileSearcher) FindFile(searchPath, namePattern string) (err error) {

    queue := make([]string, 0)
    queue = append(queue, searchPath)

    for len(queue) > 0 {
        path := queue[0]
        curFileName := filepath.Base(path) // get the file/directory name at this path
        queue = queue[1:]                  // pop off the head

        if matched, err := filepath.Match(namePattern, curFileName); err == nil && matched {
            if foundFile, err := NewFileFromPath(path); err == nil {
                fe.Contents = append(fe.Contents, *foundFile) // found a match
            }
        }

        if isDir, _ := utils.IsDirectory(path); isDir {
            if files, err := ioutil.ReadDir(path); err == nil {
                for _, f := range files {
                    fPath := filepath.Join(path, f.Name())
                    queue = append(queue, fPath) // push the new dir path to queue
                }
            }
        }
    }
    return
}
  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
    • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
    • ¥16 mybatis的代理对象无法通过@Autowired装填
    • ¥15 可见光定位matlab仿真
    • ¥15 arduino 四自由度机械臂
    • ¥15 wordpress 产品图片 GIF 没法显示
    • ¥15 求三国群英传pl国战时间的修改方法
    • ¥15 matlab代码代写,需写出详细代码,代价私
    • ¥15 ROS系统搭建请教(跨境电商用途)
    • ¥15 AIC3204的示例代码有吗,想用AIC3204测量血氧,找不到相关的代码。