Golang文本去重的代码优化问题

不好意思啊,第一次学Golang,写了个文本去重来练习,文本内容大概75万行,用go test看了下最后的去重时间,需要17's,想知道还有哪里可以优化的。

代码如下

package distinct

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "strings"
)

//DistinctFile 为指定文件去重
func DistinctFile(file string, output string) {
    // 读取需要去重的文件内容
    f, _ := os.Open(file)
    defer func() {
        ferr := f.Close()
        if ferr != nil {
            fmt.Println(ferr.Error())
        }
    }()

    reader := bufio.NewReader(f)

    // 去重map
    var set = make(map[string]bool, 0)
    // 去重后的结果
    var result string

    for {
        line, isPrefix, err := reader.ReadLine()

        if err != nil {
            break
        }

        if !isPrefix {

            lineStr := string(line)

            // key存在则跳出本次循环
            if set[lineStr] {
                continue
            }

            result += fmt.Sprintf("%s\n", lineStr)

            set[lineStr] = true
        }
    }

    // 写入另一个文件
    nf, _ := os.Create(output)
    io.Copy(nf, strings.NewReader(result))

    defer nf.Close()
}

go test的结果是17.654s

package distinct

import "testing"

func TestDistinctFile(t *testing.T) {
    DistinctFile("result.txt", "out.txt")
}

希望师傅们能指点一二

阅读 4.4k
2 个回答

var result string使用字符串拼接改为使用strings.Builder提高字符串拼接性能。

var set = make(map[string]bool, 0)改为var set = make(map[string]struct{}, 1000)先预分配1000个空间减少扩容.

当前代码完全使用的一个协程在跑。io和计算要相互等待。可以考虑通过并行的方式去分段去读取文件(就像多线程下载一样),然后把读取的内容通过channel 发送给一个专门计算去重的协程(这个地方如果想用并行计算的话会比较麻烦,牵涉到多个协程将计算结果合并。所以暂时可以先不考虑)。最后再输出到文件。

多协程读取文件的方式可以参考如下文件:

  1. Leveraging Multithreading To Read Large Files Faster In Go
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏