本文翻譯自 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)