nodejs, 多 IO 操作,如何提高执行效率?? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
actto
V2EX    Node.js

nodejs, 多 IO 操作,如何提高执行效率??

  •  
  •   actto 2017-04-21 11:25:31 +08:00 5354 次点击
    这是一个创建于 3171 天前的主题,其中的信息可能已经有所发展或是发生改变。

    主要操作:(文件去重)

    function files_do(){ let MD5 = 读(buffer 生成 MD5); if(从数据库找相同 MD5 的值.Count()==0){ //没找到 数据库.insert(文件信息); }else{ //有相同值 文件移动(原路径, 目标路径); } setTimeout(function(){ files_do() },0) } 

    目前 5 万个文件(大小: 几 k 到十几 M 都有), 大概需要 6 个小时多..

    需要处理几百万个文件.

    有什么办法能进一步提高执行效率??

    15 条回复    2017-04-22 14:19:20 +08:00
    TJT
        1
    TJT  
       2017-04-21 12:24:49 +08:00   1
    先分析性能消耗在哪里。可能的优化方法有数据库所有的 MD5 放到 Set 里面,这样就直接干掉数据库了、多线程 /多进程、用 C 重写。
    crayygy
        2
    crayygy  
       2017-04-21 12:34:54 +08:00 via iPhone   1
    粗略的想了一下,主要的消耗有两个,一是读文件, IO 消耗比较大,二是数据库查询,消耗也不小。第一个没办法,如果你对内容要求不多,直接对整个文件做校验或许就可以了。数据库的话就像楼上说的,几万个也不多,直接存在内存里,然后统一写数据库。
    XiaoxiaoPu
        3
    XiaoxiaoPu  
       2017-04-21 13:14:05 +08:00   1
    不要直接比较 md5 ,先比较文件长度,再比较文件的部分内容(比如开头 1 KiB ),最后比较 md5 。
    keller
        4
    keller  
       2017-04-21 13:18:50 +08:00   1
    不要直接对比 md 先对比文件大小 相同大小的文件再做 md5 对比
    actto
        5
    actto  
    OP
       2017-04-21 17:39:34 +08:00
    谢谢大家!!!
    1, 我目前就用的内存数据库, 定期写回 db 文件里..所以目前数据库查询效率还可以.
    2, "先比较文件大小" 不可行..因为 db.insert(文件信息) 必须有 MD5 值(因为后面的文件需要和它比对)....也还是得读一遍文件 buffer...
    3, 现在考虑用 C++写 多线程读 buffer,并生成 MD5 的操作..先写入数据库..全部结束后, 数据库查重复, 再移动文件.
    lldld
        6
    lldld  
       2017-04-21 18:40:40 +08:00 via iPhone
    @actto 楼上
    @XiaoxiaoPu 的建议不错。
    读文件的时候不要读整个文件求 md5.

    可以分三步:
    1) 按照文件大小和文件前 256bytes 的 md5 来确定可能会重复的文件
    2) 对 1 的结果求整个文件的 md5, 确定重复的文件
    3) 去重
    coderfox
        7
    coderfox  
       2017-04-21 22:57:49 +08:00 via Android
    读 buffer 生成 MD5 可以换成调用 md5 终端指令。也许能改善,取决于 node 的 md5 实现如何。
    breeswish
        8
    breeswish  
       2017-04-22 00:07:53 +08:00
    md5 没啥性能瓶颈的,一般单核每秒都有几百兆。楼主需要先看一下 node CPU 是否跑满单核了,按照楼主 po 的代码来看是有异步性能浪费的( setTimeout ),当然实际代码也许不是长成这样。如果单核已经跑满了,可以考虑上多个进程并行运行。
    优化的上线应当接近于这 5 万个文件全部读取一遍的性能。
    breeswish
        9
    breeswish  
       2017-04-22 00:16:50 +08:00
    另外楼主可以考虑直接将文件流 pipe 到 hash ,可以避免频繁的 buffer alloc ,进一步压榨一些性能。
    用 C++ 生成 md5 就不用想了, nodejs 人家不是用 js 算的 md5 ,是 openssl 计算的,自己写的效率一般不会更高。
    breeswish
        10
    breeswish  
       2017-04-22 00:23:12 +08:00
    当然上面说的那些的前提是不频繁访问数据库。数据库一般是个瓶颈,一楼已经给出优化数据库的方法了。
    不过不建议用 C 重写 :P 这个需求的终极瓶颈理论上在 IO ,如果测下来瓶颈不在 IO 上那么就是可以优化的。以及既然终极瓶颈是 IO ,那么我猜测不用异步写 C 的话会写得单核性能比 nodejs 版还要低。
    actto
        11
    actto  
    OP
       2017-04-22 00:56:30 +08:00 via Android
    @breeswish 谢谢给出的建议!!!
    我的代码确实有用到 setTimeout ,因为希望页面上能反应出进度,给 dom 操作留点时间。(electron 小程序,数据库用的 LokiJS)
    整体代码就是递归循环整个文件夹,找到所有的文件去重。重复文件放在固定文件夹,等待人工检查。
    cpu 目前占用 20%不到(18% 19%左右)。
    guokeke
        12
    guokeke  
       2017-04-22 05:45:24 +08:00
    @breeswish 你玩 telegram 吗?喵?
    breeswish
        13
    breeswish  
       2017-04-22 12:10:15 +08:00
    @guokeke breezewish
    breeswish
        14
    breeswish  
       2017-04-22 12:19:34 +08:00
    @actto 这么来说目测你的 IO 用的也都是同步的 IO 了……?那么你首先要做的是全改成异步的 IO ,然后用上一些异步流程控制的库比如 caolan/async 来进行控制(比如可以用上它的 queue )。然后 setTimeout 可以去掉了
    qfdk
        15
    qfdk  
    PRO
       2017-04-22 14:19:20 +08:00 via iPhone
    你把文件合并一下 大体看看读取 500m 是个啥速度 按道理 应该不慢 另外读取文件有异步和同步两种方式
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4470 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 04:01 PVG 12:01 LAX 20:01 JFK 23:01
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86