节点文件行数

我得到的反馈是,这个节点函数在获取文件的行数方面有性能问题,但是还没有能够精确定位细节。

function countFileLines(filePath){ return new Promise((resolve, reject) => { let lineCount = 0; fs.createReadStream(filePath) .on("data", (buffer) => { buffer.forEach((chunk) => { if (chunk === 10) lineCount++; }); }).on("end", () => { resolve(lineCount); }).on("error", reject); }); }; 

在Node中获取文件的行数是否有更高性能的方法?

我只能推测,但buffer.forEach调用一个函数,并对每个字节进行比较可能是问题。 考虑使用indexOf让VM为你find换行符:

 function countFileLines(filePath){ return new Promise((resolve, reject) => { let lineCount = 0; fs.createReadStream(filePath) .on("data", (buffer) => { let idx = -1; lineCount--; // Because the loop will run once for idx=-1 do { idx = buffer.indexOf(10, idx+1); lineCount++; } while (idx !== -1); }).on("end", () => { resolve(lineCount); }).on("error", reject); }); }; 

这个解决scheme的function是使用.indexOffind第一个换行符的位置。 它递增lineCount ,然后find下一个位置。 .indexOf的第二个参数告诉从哪里开始寻找换行符。 这样我们就跳过了大块的缓冲区。 while循环将为每个换行运行一次,再加一个。

我们让节点运行时执行search我们在较低的水平上实施,应该更快。

在我的系统上,这大约是在大文件(111 MB)上运行for循环缓冲区长度的两倍。

 function countFileLines(filePath){ return new Promise((resolve, reject) => { let lineCount = 0; let i = 0; fs.createReadStream(filePath) .on("data", (buffer) => { for (i = 0; i < buffer.length; ++i) { if (buffer[i] == 10) lineCount++; } }).on("end", () => { resolve(lineCount); }).on("error", reject); }); }; 

作比较:

原始: node index.js 2.38s user 0.29s system 98% cpu 2.713 total

修改: node index2.js 0.18s user 0.04s system 96% cpu 0.225 total