Go语言百万级文本去重性能优化
本文分析并优化一个go语言文本去重程序,该程序处理约75万行文本文件,耗时约17秒。我们将通过改进代码,提升其处理效率。
原始代码(略,原文已给出)的主要性能瓶颈在于:
字符串拼接: 使用var result string进行字符串拼接,效率低下。map容量未预分配: var set = make(map[string]bool, 0)未预分配map容量,导致频繁扩容。map值类型: 使用bool作为map的值类型,略微浪费内存。
优化后的代码:
package distinctimport ( "bufio" "fmt" "io" "os" "strings")//distinctfile 为指定文件去重func distinctfile(file string, output string) { // 读取需要去重的文件内容 f, err := os.Open(file) if err != nil { fmt.Println("Open file error:", err) return } defer f.Close() // 简化defer语句 reader := bufio.NewReader(f) // 去重map,预分配容量,使用struct{}作为值类型 set := make(map[string]struct{}, 750000) // 预分配与文件行数大致相同的容量 var result strings.Builder for { line, isPrefix, err := reader.ReadLine() if err == io.EOF { break // 更清晰的EOF处理 } if err != nil { fmt.Println("Readline error:", err) return } if !isPrefix { lineStr := string(line) if _, ok := set[lineStr]; !ok { // 更简洁的判断key是否存在 result.WriteString(lineStr + "") set[lineStr] = struct{}{} } } } // 写入另一个文件 nf, err := os.Create(output) if err != nil { fmt.Println("Create file error:", err) return } defer nf.Close() _, err = io.Copy(nf, strings.NewReader(result.String())) // 使用result.String() if err != nil { fmt.Println("Copy error:", err) return }}
登录后复制
改进说明:
使用strings.Builder代替字符串拼接,显著提高效率。预分配map容量为750000,接近文件行数,减少扩容操作。使用struct{}作为map的值类型,节省内存。使用更清晰的错误处理和defer语句。使用result.String()获取最终结果字符串。
进一步优化建议:
立即学习“go语言免费学习笔记(深入)”;
并发处理: 将文件分割成多个部分,使用goroutine并发处理,再合并结果。这对于更大规模的文件非常有效。更高效的数据结构: 对于极大规模的数据,可以考虑使用bloom filter等概率数据结构来提高查找效率,虽然会有一定的误判率,但可以大幅提升速度。内存映射: 使用mmap将文件映射到内存,减少IO操作。
通过以上优化,可以显著提升Go语言文本去重程序的性能。 选择哪种优化策略取决于具体的需求和数据规模。 对于百万级数据,并发处理和预分配map容量是比较有效的优化手段。
以上就是Go语言文本去重:如何优化百万级文本文件的去重速度?的详细内容,更多请关注【创想鸟】其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。
发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2538329.html