• 请不要在回答技术问题时复制粘贴 AI 生成的内容
sl19981007
V2EX  ›  程序员

大文本按行去重(2G 左右文件)有什么好的解决方案吗?

  •  
  •   sl19981007 · Nov 10, 2020 · 6572 views
    This topic created in 2184 days ago, the information mentioned may be changed or developed.

    速度可以稍慢一点,但也不能太慢(一两个小时跑不完那种 不使用 Spark 之类的计算引擎 麻烦大佬们给小弟个解决方案

    36 replies  •  2020-11-11 20:57:52 +08:00
    aloxaf
    aloxaf
    Nov 10, 2020❤️1
    1
    2G 算啥大文本,不要求保持原始顺序的话直接 `sort -u` 就行了。
    skypyb
    skypyb
    Nov 10, 2020
    2
    可以接受一点点误差的话
    布隆过滤器
    loliordie
    loliordie
    Nov 10, 2020 via Android
    3
    随便挑个语言 load 到内存里 o(n)复杂度迭代一次就完事了

    会用 pandas 用 pandas 不会就用 python 的 set 来实现 处理速度基本等同于 io 的速度
    liangfengmark
    liangfengmark
    Nov 10, 2020
    4
    python set
    sl19981007
    sl19981007
    OP
    Nov 10, 2020
    5
    @loliordie 好吧,我没说清楚,我们同时间可能会有多个这种去重的任务。
    way2explore2
    way2explore2
    Nov 10, 2020❤️1
    6
    @loliordie 正解,2g 直接内存
    GM
    GM
    Nov 10, 2020
    7
    直接 sort -u,磁盘速度够的话,一分钟完事
    icyalala
    icyalala
    Nov 10, 2020❤️3
    8
    2G 直接哈希表都能搞定,甚至直接 awk 一行命令:
    awk '!a[$0]++' input.txt > output.txt
    t6attack
    t6attack
    Nov 10, 2020
    9
    <?php
    ini_set('memory_limit',-1);
    $array = file('源文件.txt');
    $array = array_unique($array);
    file_put_contents('输出文件.txt',implode($array,""));
    ?>
    我一直用的方法。也就上面有人说的,直接内存处理。
    loliordie
    loliordie
    Nov 10, 2020 via Android❤️1
    10
    @sl19981007 取决于你的 tradeoff 是空间复杂度优先还是时间复杂度优先

    如果是要多个任务同时处理时间复杂度优先 内存够大直接搞个 celery 之类的多线程库就行了 内存不够大就锁队列 只允许 n 个任务同时运行

    更简单一点可以输入多个路径 挨个处理 连多线程库都不用上 就是同时只能有一个任务正在运行 但你这个需求 最大瓶颈在于硬盘 io 所以多个并行或者串行影响都不大
    mengzhuo
    mengzhuo
    Nov 10, 2020❤️1
    11
    才 2G,直接上哈希表干就完了

    一堆超大文件倒是可以试试我的 nabhash
    http://nabhash.org/
    aladdindingding
    aladdindingding
    Nov 10, 2020
    12
    linux 命令就行 sort | unique
    MOONLIGHTT
    MOONLIGHTT
    Nov 10, 2020
    13
    别自己写,用 linux 的内建命令
    knightdf
    knightdf
    Nov 10, 2020
    14
    2G 而已,sort 都挺快的
    hotpot6147
    hotpot6147
    Nov 10, 2020
    15
    2g 的文本直接 load 进内存,然后 hash 去重就可以了。

    如果 pc 机内存不够可以对每行数据进行 hash 后取模分布在 n 个文件中,然后再将这 n 个文件分别 load 进内存去重
    BBCCBB
    BBCCBB
    Nov 10, 2020
    16
    我感觉这种都是先遍历, 按文本 hash 拆分成足够小的文件, 然后在内存足够的情况下去处理每个小文件, 最后 merge 起来就完成了你说的需求了..


    一般都是按 hash 拆分, 然后处理每个小文件, 最后再合并.
    BBCCBB
    BBCCBB
    Nov 10, 2020
    17
    不过这是针对超大文件的, 你这个 2G 真的可以试试直接 load 到内存.
    Xusually
    Xusually
    Nov 10, 2020
    18
    我开个脑洞,存数据库里。单行内容做主键,不停按行 insert,emmm......
    gainsurier
    gainsurier
    Nov 10, 2020
    19
    emeditor,十几秒搞定
    aec4d
    aec4d
    Nov 10, 2020
    20
    瓶颈是磁盘 IO, 针对选一个 hash https://github.com/rust-lang/hashbrown,按行读取,如果 hash 值已存在则跳过,猜测十秒能完成吧
    janxin
    janxin
    Nov 10, 2020
    21
    这数据量直接 load 到内存里怎么玩都行
    NCE
    NCE
    Nov 10, 2020
    22
    这应该是个面试题
    winglight2016
    winglight2016
    Nov 10, 2020
    23
    @NCE 的确,我在金山面试 android 时有被问过类似问题
    nowgoo
    nowgoo
    Nov 10, 2020
    24
    linux 环境 sort/awk,windows 环境 editplus/emeditor
    rainfd
    rainfd
    Nov 10, 2020
    25
    sort | unique
    m30102
    m30102
    Nov 10, 2020
    26
    LinekdHashSet 行不?
    Mohanson
    Mohanson
    Nov 10, 2020
    27
    任意"去重"或"排序"的面试题答"字典树"绝对得分的.
    fewok
    fewok
    Nov 11, 2020
    28
    @loliordie o(n)复杂度 怕是搞不定吧
    loliordie
    loliordie
    Nov 11, 2020 via Android
    29
    @fewok 为何搞不定 不就是 n 次查哈希表的操作么?
    mogami18
    mogami18
    Nov 11, 2020
    30
    我還以為是 2T
    oneoyn
    oneoyn
    Nov 11, 2020 via Android
    31
    2G 我的 cpu 可以秒开
    fewok
    fewok
    Nov 11, 2020
    32
    @loliordie 建哈希表 或者查哈希表 就不算复杂度嘛?
    newmlp
    newmlp
    Nov 11, 2020
    33
    2g 而已,全部读到内存就完事了
    vincent7245
    vincent7245
    Nov 11, 2020
    34
    所以你为什么不用 spark 呢 /狗头
    loliordie
    loliordie
    Nov 11, 2020
    35
    @fewok 你可能需要理解下 O(n)复杂度的意义, 大 O 计算法考察的是时间规模跟输入规模的关系, 哈希表复杂度为 O(1), 不会影响时间复杂度, 除非你使用了 listnode 这样的结构, 每次查询元素时都会迭代, 随着输入规模的增加查询时间也会增加这样才会导致复杂度从 O(n)变为 O(n^2)
    hxy100
    hxy100
    Nov 11, 2020
    36
    Linux 直接上 sort 或者 uniq 命令即可,Windows 下的话直接 Emeditor 打开,点一下去重按钮就完事。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   5031 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 229ms · UTC 08:01 · PVG 16:01 · LAX 00:01 · JFK 03:01
    ♥ Do have faith in what you're doing.