fs.readFileSync似乎比fs.readFile更快 - 在生产中用于Web应用程序是否可以?

时间:2012-12-11 14:42:37

标签: node.js localization io

我知道在开发节点时,你应该总是试图避免阻塞(同步)函数并使用异步函数,但是我会稍微测试一下它们的比较方法。

我需要打开一个包含i18n数据(如日期和时间格式等)的json文件,并将该数据传递给使用此数据格式化我的视图中的数字等的类。

在回调中开始包装所有类的方法会有点尴尬,所以如果可能的话,我会使用同步版本。

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倍,并且需要大约1ms来加载50KB的json文件(缩小)。我所有的json文件都在50-100KB左右。

我在考虑也许以某种方式将这个json数据记忆或保存到会话中,以便每个会话只读取一次文件(或者当用户更改其语言环境时)。我不完全确定如何做到这一点,这只是一个想法。

在我的情况下可以使用fs.readFileSync还是以后会遇到麻烦?

5 个答案:

答案 0 :(得分:64)

不,如您所述,在节点服务器中使用阻塞API调用是不正确的。您的网站对许多并发连接的响应将受到巨大冲击。它也只是公然违反节点的#1原则。

节点工作的关键是,当它在等待IO时,它正在同时进行CPU /内存处理。这需要专门的异步调用。因此,如果您有100个客户端读取100个JSON文件,节点可以要求操作系统读取这100个文件,但在等待操作系统返回文件数据时,节点可以处理这100个网络请求的其他方面。如果您在其中有一个同步调用,则所有客户端处理在该操作完成时完全停止。因此,当您按顺序读取客户端1,2,3,4等文件时,客户端编号100的连接将等待,无需任何处理。这是Failville。

这是另一个类比。如果你去了一家餐馆而且是唯一的顾客,如果一个人坐在你身边,接过你的订单,煮熟,送给你,处理账单而没有与主人打交道的协调费用,你可能会得到更快的服务。女主人,服务员,主厨,线厨师,收银员等。然而,在餐厅有100名顾客,额外的协调意味着事情并行发生,餐厅的整体响应能力超出了单身人士的情况。试图自己处理100个客户。

答案 1 :(得分:10)

您使用同步读取阻止了异步读取的回调,请记住单线程。 现在我明白时差仍然是惊人的,但你应该尝试使用一个更长,更长时间阅读的文件,并想象很多很多客户都会这样做,只有这样才能获得成本。 这应该回答你的问题,是的,如果你为数千人服务,你将遇到麻烦 阻止IO的请求。

答案 2 :(得分:0)

经过大量的时间和大量的学习与练习,我再次尝试了一下,找到了答案,并且可以举一些例子:

evolve

答案 3 :(得分:0)

是的,在服务器端环境中处理异步方式是正确的。但是,如果它们的用例不同,例如像在客户端JS项目中生成构建那样,则同时读写不同风格的JSON文件。

影响不大。尽管我们需要一种快速的方法来创建用于部署的精简版(此处是同步的图片)。 for more info and library

答案 4 :(得分:-1)

我试图检查fs.readFileSync()和fs.readFile()之间速度的真实,可衡量的差异,以便下载SD卡上的3个不同文件,并且我已经在此之间添加了下载一些数学计算,我不明白节点图片总是在节点图片上显示的速度差异在哪里也是简单的操作,如下载3次相同的文件,并且此操作的时间接近时间这个文件下载1次需要。

我理解这对于服务器在下载某个文件时能够完成其他工作无疑是有用的,但是在youtube或书籍中有很多时间,有些图表不准确,因为当你遇到类似下面的情况时节点慢于读取小文件时的同步(如下所示:85kB,170kB,255kB)。

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.