我有一个长期运行的node.js进程,我需要扫描日志文件中的模式.我有至少两个明显的选择:
spawn a grep process或使用
fs.read*读取文件并解析node.js中的缓冲区/流.我没有在intarwebs上找到两种方法的比较.我的问题有两个:
>哪个更快?
>为什么我更喜欢一种技术而不是另一种?
解决方法
这是我的nodejs实现,结果非常符合预期:
小文件运行速度比分叉grep(文件长达2-3k短线)快,
大文件运行速度较慢.文件越大,差异越大.
(也许正则表达式越复杂,差异越小 – 见
下面.)
小文件运行速度比分叉grep(文件长达2-3k短线)快,
大文件运行速度较慢.文件越大,差异越大.
(也许正则表达式越复杂,差异越小 – 见
下面.)
我使用自己的qfgets包快速
一次一行文件i / o;那里可能有更好的,我不知道.
我看到一个意外的异常,我没有调查:下面的时间
用于常量字符串regexp / foobar /.当我把它改成
/ [f] [o] [o] [b] [a] [r] /实际运用正则表达式引擎,grep减速
下降3倍,节点加速! grep的3倍减速可以重现
命令行.
filename = "/var/log/apache2/access.log"; // 2,540,034 lines,187MB //filename = "/var/log/messages"; // 25,703 lines,2.5MB //filename = "out"; // 2000 lines,188K (head -2000 access.log) //filename = "/etc/motd"; // 7 lines,286B regexp = /foobar/; child_process = require('child_process'); qfgets = require('qfgets'); function grepWithFs( filename,regexp,done ) { fp = new qfgets(filename,"r"); function loop() { for (i=0; i<40; i++) { line = fp.fgets(); if (line && line.match(regexp)) process.stdout.write(line); } if (!fp.feof()) setImmediate(loop); else done(); } loop(); } function grepWithFork( filename,done ) { cmd = "egrep '" + regexp.toString().slice(1,-1) + "' " + filename; child_process.exec(cmd,{maxBuffer: 200000000},function(err,stdout,stderr) { process.stdout.write(stdout); done(err); }); }
考试:
function fptime() { t = process.hrtime(); return t[0] + t[1]*1e-9 } t1 = fptime(); if (0) { grepWithFs(filename,function(){ console.log("fs done",fptime() - t1); }); } else { grepWithFork(filename,function(err){ console.log("fork done",fptime() - t1); }); }
结果:
/** results (all file contents memory resident,no disk I/O): times in seconds,best run out of 5 /foobar/ fork fs motd .00876 .00358 0.41 x 7 lines out .00922 .00772 0.84 x 2000 lines messages .0101 .0335 3.32 x 25.7 k lines access.log .1367 1.032 7.55 x 2.54 m lines /[f][o][o][b][a][r]/ access.log .4244 .8348 1.97 x 2.54 m lines **/
编辑:突出显示关键结果:
185MB,254万行,搜索RegExp / [f] [o] [o] [b] [a] [r] /:
grepWithFs
已过去:.83秒
grepWithFork
已过去:.42秒
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。