本文翻译自 How to read files quickly in JavaScript,作者:Daniel Lemire, 略有删改。
假设你需要在服务器上使用JavaScript读取多个文件。在像Node.js这样的运行时环境中,JavaScript有多种读取文件的方式。哪一种是最好的呢?让我们来看看各种方法的测试结果。
使用fs. promise
const fs = require('fs/promises');
const readFile = fs.readFile;
readFile("lipsum.txt", { encoding: 'utf-8' })
.then((data) => {...})
.catch((err) => {...})
使用fs.readFile和util.promisify
const fs = require('fs');
const util = require('util');
const readFile = util.promisify(fs.readFile);
readFile("lipsum.txt", { encoding: 'utf-8' })
.then((data) => {...})
.catch((err) => {...})
使用fs.readFileSync
const fs = require('fs');
const readFileSync = fs.readFileSync;
var data = readFileSync("lipsum.txt", { encoding: 'utf-8' })
使用await fs.readFileSync
const fs = require('fs');
const readFileSync = fs.readFileSync;
async function f(name, options) {
return readFileSync(name, options);
}
使用fs.readFile
const fs = require('fs');
const readFile = fs.readFile;
fs.readFile('lipsum.txt', function read(err, data) {...});
测试
我写了一个小型基准测试,用于反复从磁盘读取文件。这是一个简单的循环,每次都会访问相同的文件。我记录了读取文件5万次所需的毫秒数。这个文件相对较小(略超过1千字节)。我使用的是一台拥有数十个Ice Lake Intel核心和大量内存的大型服务器。我使用的Node.js版本是20.1
,Bun版本是1.0.14
。
我多次运行了基准测试,并且在所有情况下都记录了最好的结果。你的结果可能会有所不同。
时间(Node.js) | 时间(Bun) | |
---|---|---|
fs.promises | 2400 ms | 110 ms |
fs.readFile和util.promisify | 1500 ms | 180 ms |
fs.readFileSync | 140 ms | 140 ms |
await fs.readFileSync | 220 ms | 180 ms |
fs.readFile | 760 ms | 90 ms |
至少在我的系统上,在这个测试中使用Node.js时,fs.promises
比其他方式都要慢的多。在这个测试中Bun比Node.js快得多。
从某种意义上来说,fs.promises
的结果比看上去更差。我发现 readFileSync
使用了 300 毫秒的 CPU 时间,而 fs.promises
却使用了 7 秒的 CPU 时间。这是因为在进行基准测试时,fs.promises
在多个核心上触发了工作。
即使将文件大小增加到32kB,结论也并没有改变。如果你使用更大的文件,许多Node.js案例会因为“堆内存分配失败”而失败。但Bun即使处理大文件也能继续运行。测试结果并没有改变关于Bun的结论:在我的测试中,fs.readFile
始终更快,即使对于大文件也是如此。
看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~
专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。