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

我知道在node中开发的时候,应该尽量避免使用asynchronous函数,但是我稍微testing一下,看看它们是如何比较的。

我需要打开一个包含i18n数据(如date和时间格式等)的json文件,并将这些数据传递给使用这些数据格式化数据的类。

开始将所有类的方法包装在callback函数中会有些尴尬,所以如果可能的话,我会使用同步版本。

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还是会在以后遇到麻烦?

不,在您描述的节点服务器中使用阻塞API调用是不行的。 您的网站对许多并发连接的响应速度将会很快。 这也只是公然违反节点的第一原则。

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

这是另一个比喻。 如果你去了一家餐馆,并且是唯一的顾客,那么如果一个人坐在你身边,接受你的订单,烹饪,送达给你,并且处理账单,而没有处理主人/女主人,服务员,主厨,厨师,收银员等等。然而,在餐馆中有100位顾客,额外的协调意味着事情并行发生,餐厅的整体响应度增加了,超出了单个人试图自己处理100个客户。

您正在使用同步读取阻止asynchronous读取的callback,请记住单个线程 。 现在我明白,时间差异仍然是惊人的,但是你应该尝试一个更长的文件来阅读和想象许多许多客户也会这样做,只有这样开销才会有回报。 这应该回答你的问题,如果你正在服务数千个阻塞IO的请求,你会遇到麻烦。

我试图检查fs.readFileSync()和fs.readFile()之间的速度真正的,可测量的差异,下载3个不同的SD卡上的文件,我已经添加了这个下载之间的一些math计算,我不不知道节点快时节点上显示的速度的差异在哪里,比如下载同一个文件3次这样简单的操作,这个操作的时间接近下载这个文件一次所需要的时间。

我知道这无疑是有用的,下载一些文件时,服务器可以做其他工作,但在YouTube上或书中有很多时间,有一些图不精确,因为当你像下面的情况asynchronous节点较慢然后同步读取小文件(如下: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.