gpt4 book ai didi

node.js - 为什么 fs.readFileSync() 比 await fsPromises.readFile() 快?

转载 作者:行者123 更新时间:2023-12-03 12:12:48 24 4
gpt4 key购买 nike

这是测试代码(在 express 环境中,只是因为我碰巧在弄乱它):

const fs = require('fs-extra');
const fsPromises = fs.promises;
const express = require('express');
const app = express();

const speedtest = async function (req, res, next) {
const useFsPromises = (req.params.promises == 'true');
const jsonFileName = './json/big-file.json';
const hrstart = process.hrtime();
if (useFsPromises) {
await fsPromises.readFile(jsonFileName);
} else {
fs.readFileSync(jsonFileName);
}
res.send(`time taken to read: ${process.hrtime(hrstart)[1]/1000000} ms`);
};

app.get('/speedtest/:promises', speedtest);
big-file.json文件大约 16 MB。使用 Node 12.18.4。
典型结果(围绕这些值有很大差异,但以下是“典型”结果):
https://dev.mydomain.com/speedtest/false
time taken to read: 3.948152 ms

https://dev.mydomain.com/speedtest/true
time taken to read: 61.865763 ms
更新 包括另外两个变体...普通 fs.readFile()还有一个 promise 的版本:
const fs = require('fs-extra');
const fsPromises = fs.promises;
const util = require('util');
const readFile = util.promisify(fs.readFile);
const express = require('express');
const app = express();

const speedtest = async function (req, res, next) {
const type = req.params.type;
const jsonFileName = './json/big-file.json';
const hrstart = process.hrtime();
if (type == 'readFileFsPromises') {
await fsPromises.readFile(jsonFileName);
} else if (type == 'readFileSync') {
fs.readFileSync(jsonFileName);
} else if (type == 'readFileAsync') {
return fs.readFile(jsonFileName, function (err, jsondata) {
res.send(`time taken to read: ${process.hrtime(hrstart)[1]/1000000} ms`);
});
} else if (type == 'readFilePromisified') {
await readFile(jsonFileName);
}
res.send(`time taken to read: ${process.hrtime(hrstart)[1]/1000000} ms`);
};

app.get('/speedtest/:type', speedtest);
我发现 fsPromises.readFile()是最慢的,而其他的要快得多,并且在阅读时间方面大致相同。我应该在 different example 中添加它(我无法完全验证,所以我不确定发生了什么)时差比这里报告的要大得多。目前在我看来 fsPromises.readFile()应该简单地避免,因为还有其他异步/ promise 选项。

最佳答案

在调试器中逐步执行每个实现( fs.readFileSyncfs.promises.readFile )后,我可以确认同步版本以一个大块(文件的大小)读取整个文件。而fs.promises.readFile()在循环中一次读取 16,384 个字节,带有 await每次阅读。这将使fs.promises.readFile()在它可以读取整个文件之前多次返回事件循环。除了给其他东西一个运行的机会之外,在每个循环中通过 for 返回到事件循环是额外的开销。环形。还有内存管理开销,因为 fs.promises.readFile()分配一系列 Buffer 对象,然后在最后将它们组合起来,而 fs.readFileSync()在开始时分配一个大的 Buffer 对象,然后将整个文件读入那个 Buffer。
因此,允许占用整个 CPU 的同步版本从纯时间到完成的角度来看更快(从多用户服务器中使用的 CPU 周期的角度来看,它的效率要低得多,因为它阻止了在读取期间执行任何其他操作的事件循环)。异步版本以较小的块读取,可能是为了避免过多地阻塞事件循环,以便其他事情可以有效地交错和运行,而 fs.promises.readFile()正在做它的事情。
对于我不久前参与的一个项目,我编写了自己的简单异步版本 readFile()一次读取整个文件,它比内置实现快得多。我并不担心那个特定项目中的事件循环阻塞,所以我没有调查这是否是一个问题。

另外,fs.readFile()以 524,288 字节块(比 fs.promises.readFile() 大得多的块)读取文件并且不使用 await ,只使用简单的回调。它显然只是比 promise 实现更优化编码。我不知道为什么他们为 fs.promises.readFile() 以较慢的方式重写了该函数执行。现在,似乎包装 fs.readFile()有 promise 会更快。

关于node.js - 为什么 fs.readFileSync() 比 await fsPromises.readFile() 快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63971379/

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