gpt4 book ai didi

node.js - 来自 node.js,哪个更快,shell grep 还是 fs.readFile?

转载 作者:搜寻专家 更新时间:2023-10-31 22:18:06 25 4
gpt4 key购买 nike

我有一个长时间运行的 node.js 进程,我需要扫描日志文件以寻找模式。我至少有两个明显的选择:spawn a grep process或使用 fs.read* 读取文件并解析 node.js 中的缓冲区/流。我还没有在 intarwebs 上找到这两种方法的比较。我的问题是双重的:

  1. 哪个更快?
  2. 为什么我可能更喜欢一种技术而不是另一种?

最佳答案

这是我的 nodejs 实现,结果与预期的差不多:小文件比 fork 的 grep 运行得更快(文件最多 2-3k 短行),大文件运行速度较慢。文件越大,差异越大。(也许正则表达式越复杂,差异越小——见下面。)

我用的是自己的qfgets快速包装一次一行的文件输入/输出;可能还有更好的,我不知道。

我看到了一个我没有调查的意外异常:以下时间用于常量字符串正则表达式 /foobar/。当我把它改成/[f][o][o][b][a][r]/ 实际运行正则表达式引擎,grep 变慢了下降了 3 倍,而 Node 加速了! 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, regexp, 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, regexp, function(){
console.log("fs done", fptime() - t1);
});
}
else {
grepWithFork(filename, regexp, 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

经过:0.83 秒

grepWithFork

经过:0.42 秒

关于node.js - 来自 node.js,哪个更快,shell grep 还是 fs.readFile?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28400727/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com