为什么在nodejs中读取10个50MB的文件与读取1个500MB的文件花费相同的时间?

问题描述 投票:0回答:1
// fulfill one promise 5000ms
console.time('test');

(async function () {
  await new Promise((resolve) => setTimeout(resolve, 5000));
  console.log('slept')
})()
  .then(() => {
    console.timeEnd('test');
  })
// Time ~5000 мс
// fulfill 10 promises by 500ms
console.time('test');

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

let test = [];

(async function () {
  test = await Promise.all(
    arr.map((elem) => new Promise(async (resolve) => setTimeout(resolve, 500)))
  )
  console.log(test.length)
  console.log('raided')
})()
  .then(() => {
    console.timeEnd('test');
  })

// Time ~500 мс
// Read file 500mb
const fs = require('node:fs');

console.time('test');

let test;

(async function () {
  test = fs.readFileSync('./assets/500mb');
  console.log('raided', test.length)
})()
  .then(() => {
    console.timeEnd('test');
  })
// Time ~300 мс
// Read 10 files by 50mb
const fs = require('node:fs');

console.time('test');

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

let test = [];

(async function () {
  test = await Promise.all(
    arr.map((elem) => new Promise((resolve) => fs.readFile(`./assets/50mb_${elem}`, resolve)))
  )

  console.log(test.length)
  console.log('raided')
})()
  .then(() => {
    console.timeEnd('test');
  })
// Time ~300ms

执行前两段代码后,我们会得到大约10倍的执行速度差异。这通常是可以理解的。但如果我们读取文件而不是 setTimeout,我们就不会得到这种增加。为什么?充分解释一下,我知道读取文件不是由节点完成的,但是那里发生了什么?为什么我们不能获得至少 2 倍的增长?第三个和第四个代码的时间相同,无论您读取一个 500 MB 的文件还是读取 10 个 50 MB 的文件,都没有区别。为什么?

我想自己弄清楚,但我无法弄清楚。

node.js asynchronous promise readfile node.js-fs
1个回答
0
投票

setTimeout
一段时间后调用函数。在调用
setTimeout
和调用回调之间的时间里,它 没有做任何工作。它只是偶尔检查一下时钟。

readFile
读取文件。当文件被读入内存时,回调被调用。读取文件是工作。计算机只能以这么快的速度从磁盘上提取数据。它无法并行读取多个文件,同时保持每个文件的每秒字节数与一次读取一个文件相同。由于
readFile
是异步的,它不会阻塞 JS 事件循环,因此 JS 程序可以同时做其他事情(例如更新显示或通过网络发送消息),但计算机的磁盘读取部分是对于任何想要从磁盘读取的东西来说都是一个瓶颈。


如果你喜欢打个比方:

setTimeout
就像在说“一小时内敲响钟声”。你可以坐在椅子上等待。

readFile
就像说“去学校接孩子,然后按响铃”,还有“去商店拿牛奶,然后按响铃”,还有“去公园散步神” ,然后按响铃”。每项任务都需要 1 小时,但您很难在一小时内完成“所有”任务。您需要 3 小时才能完成全部 3 项工作。

© www.soinside.com 2019 - 2024. All rights reserved.