minhash不适合单字符串去重,它专为多文档集合的近似相似度估算设计;单行日志去重应直接用map[string]struct{}配合bufio.scanner,超大文件需哈希分治,仅在亿级短文本模糊去重时才适用minhash。

MinHash 不适合单字符串去重
MinHash 本质是为「多文档集合」设计的近似相似度估算工具,不是为单个超长字符串内部行/片段去重用的。如果你手头是一份含千万行日志的 log.txt,想筛掉重复行——别碰 MinHash,它解决的是“哪两篇文档像”,不是“这一行要不要留”。强行套用只会多占内存、多绕弯路、结果还不准。
小文件(≤5000万行)直接用 map[string]struct{} + bufio.Scanner
这是最稳、最快、最容易写对的路径,但有三个硬约束必须满足:
-
map[string]struct{}而非map[string]bool:省下约 40% 内存,尤其在键多时差异明显 - 用
strings.TrimSpace(line)处理scanner.Text()结果:空行、BOM、尾部空格不处理会导致同一行被当成不同 key - 额外维护
[]string记录首次出现顺序:因为map迭代不保序,输出要按原顺序就得这么干
超大文件(>5000万行)必须哈希分治,避免 OOM
内存装不下全部 key 时,map 不是慢,而是根本跑不起来。核心原则只有一条:相同内容必须进同一个桶。推荐做法:
- 用
sha256.Sum32(line) % N分桶(N=100~1000),比fnv更抗倾斜 - 每个桶内仍用
map[string]struct{}去重,最后合并结果 - 别把所有桶同时加载进内存:逐个处理,写完一个桶就 flush,否则和不分治没区别
真要模糊去重(如近似重复句子)才考虑 MinHash
比如你有一亿条短文本(每条 100 字以内),需要找出“内容相似度 ≥ 0.8”的组,这时才轮到 MinHash 上场。但它必须配合 shingling(如 char_shingles(text, width=5))和 LSH 加速,且最终还得二次校验。单独拿 MinHash 算一个字符串的“内部去重”,既没语义也没实现路径——它不接收单字符串输入,只接收一组文档的 shingle 集合。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











