NodeJS fs.readFileSync似乎比fs.readFile更快-它可以用于生产中的Web应用程序吗?

qhhrdooz  于 2022-12-22  发布在  Node.js
关注(0)|答案(5)|浏览(268)

我知道当在node中开发时,你应该总是尽量避免阻塞(sync)函数,而使用async函数,但是,我做了一个小测试来比较它们。
我需要打开一个包含i18 n数据(如日期和时间格式等)的JSON文件,并将该数据传递给一个类,该类使用该数据来格式化视图中的数字等。
在回调中开始 Package 类的所有方法会有点笨拙,所以如果可能的话,我将使用同步版本。

console.time('one');
console.time('two');
fs.readFile( this.dir + "/" + locale + ".json", function (err, data) {
  if (err) cb( err );
  console.timeEnd('one');
});
var data = fs.readFileSync( this.dir + "/" + locale + ".json" );
console.timeEnd('two');

这将在我的控制台中生成以下行:

two: 1ms
one: 159ms

看起来fs.readFileSync比fs.readFile快150倍-加载一个50 KB的JSON文件(缩小版)大约需要1毫秒。我所有的JSON文件都在50- 100 KB左右。
我还在想,也许可以通过某种方式将这些JSON数据存储或保存到会话中,以便每个会话(或当用户更改他们的区域设置时)只读取一次文件。我不完全确定如何做到这一点,这只是一个想法。
在我的情况下使用fs.readFileSync可以吗?或者以后会遇到麻烦吗?

jjjwad0x

jjjwad0x1#

不,在你描述的节点服务器中使用阻塞API调用是不对的。你的站点对许多并发连接的响应将受到巨大的打击。这也公然违反了节点的第一原则。
节点工作的关键是,当它等待IO时,它同时进行CPU/内存处理。这需要专门的异步调用。因此,如果您有100个客户端阅读100个JSON文件,节点可以要求操作系统读取这100个文件,但在等待操作系统返回可用的文件数据时,节点可能正在处理这100个网络请求的其他方面。如果您有一个同步调用,则在该操作完成时,所有客户端处理都将完全停止。因此,当您读取客户端1、2 3,4,依次类推,这是费维尔。
再打个比方。如果你去一家餐馆,而且你是唯一的顾客,那么如果一个人坐在你旁边,接受你的订单,烹饪它,为你服务,并处理账单,而不需要与主人/女主人、服务员、主厨、一线厨师、收银员等打交道的协调开销,你可能会得到更快的服务。然而,如果餐馆里有100名顾客,额外的协调意味着事情并行地发生,并且餐馆的整体响应性被增加,远远超过了如果单个人试图独自处理100个顾客的情况。

v9tzhpje

v9tzhpje2#

您正在使用同步读取阻塞异步读取的回调,请记住单线程。现在我明白时间差异仍然很惊人,但您应该尝试读取长得多的文件,并想象许多许多客户端也会这样做,只有这样开销才会得到回报。这应该会回答您的问题,是的,如果你用阻塞的IO来处理成千上万的请求,你会遇到麻烦。

prdp8dxp

prdp8dxp3#

是的,这是正确的,在服务器端环境中处理异步方式。但是如果他们的用例不同,比如在客户端JS项目中生成构建,同时阅读不同风格的JSON文件。
虽然我们需要一种快速的方式来创建一个用于部署的小型构建(这里同步就进入了画面),但它并没有太大的影响。for more info and library

uyhoqukh

uyhoqukh4#

经过大量的时间和大量的学习和实践,我已经尝试了一次,我已经找到了答案,我可以展示一些例子:

const fs = require('fs');

const syncTest = () => {
    let startTime = +new Date();
    const results = [];
    const files = [];

    for (let i=0, len=4; i<len; i++) {
        files.push(fs.readFileSync(`file-${i}.txt`));
    };

    for (let i=0, len=360; i<len; i++) results.push(Math.sin(i), Math.cos(i));
    console.log(`Sync version: ${+new Date() - startTime}`);
};

const asyncTest = () => {
    let startTime = +new Date();
    const results = [];
    const files = [];

    for (let i=0, len=4; i<len; i++) {
        fs.readFile(`file-${i}.txt`, file => files.push(file));
    };

    for (let i=0, len=360; i<len; i++) results.push(Math.sin(i), Math.cos(i));

    console.log(`Async version: ${+new Date() - startTime}`);
};

syncTest();
asyncTest();
polhcujo

polhcujo5#

我试着去检查真实的的,fs.readFileSync之间速度的可测量差异()和文件系统.readFile()用于下载SD卡上的3个不同文件,我在此之间添加了一些数学计算,我不我不明白哪里是速度的差异,这是总是显示在节点图片时,节点是更快的,也在简单的操作,如下载3次相同的文件和时间操作接近下载1次此文件所需的时间。
我明白,这无疑是有用的,服务器在下载一些文件时能够做其他工作,但很多时候在YouTube或在书中有一些图表是不精确的,因为当你有一个像下面的异步节点的情况是缓慢的,然后在阅读小文件同步(如下面:85千字节、170千字节、255千字节)。

var fs = require('fs');

var startMeasureTime = () => {
  var start = new Date().getTime();
  return start;
};

// synch version
console.log('Start');
var start = startMeasureTime();

for (var i = 1; i<=3; i++) {
  var fileName = `Lorem-${i}.txt`;
  var fileContents = fs.readFileSync(fileName);
  console.log(`File ${1} was downloaded(${fileContents.length/1000}KB) after ${new Date().getTime() - start}ms from start.`);

  if (i === 1) {
    var hardMath = 3*54/25*35/46*255/34/9*54/25*35/46*255/34/9*54/25*35/46*255/34/9*54/25*35/46*255/34/9*54/25*35/46*255/34/9;  
  };
};

// asynch version
setImmediate(() => {
  console.log('Start');
  var start = startMeasureTime();

  for (var i = 1; i<=3; i++) {
    var fileName = `Lorem-${i}.txt`;
    fs.readFile(fileName, {encoding: 'utf8'}, (err, fileContents) => {
      console.log(`File ${1} was downloaded(${fileContents.length/1000}KB) after ${new Date().getTime() - start}ms from start.`);
    });

    if (i === 1) {
      var hardMath = 3*54/25*35/46*255/34/9*54/25*35/46*255/34/9*54/25*35/46*255/34/9*54/25*35/46*255/34/9*54/25*35/46*255/34/9;  
    };
  };
});

This is from console:
Start
File 1 was downloaded(255.024KB) after 2ms from start.
File 1 was downloaded(170.016KB) after 5ms from start.
File 1 was downloaded(85.008KB) after 6ms from start.
Start
File 1 was downloaded(255.024KB) after 10ms from start.
File 1 was downloaded(85.008KB) after 11ms from start.
File 1 was downloaded(170.016KB) after 12ms from start.

相关问题