为什么这个node.js循环在112050次迭代后运行缓慢?

为什么这个node.js循环在112050次迭代后运行缓慢?,node.js,performance,loops,file-io,io,Node.js,Performance,Loops,File Io,Io,我在玩node.js时发现这个简单的程序运行速度非常慢,我甚至没有等3分钟后再看它花了多长时间 var fs = require ('fs') var s = fs.createWriteStream("test.txt"); for (i = 1; i <= 1000000; i++) s.write(i+"\n"); s.end() var fs=require('fs')) var s=fs.createWriteStream(“test.txt”); 对于(i=1;i

我在玩node.js时发现这个简单的程序运行速度非常慢,我甚至没有等3分钟后再看它花了多长时间

var fs = require ('fs')
var s = fs.createWriteStream("test.txt");
for (i = 1; i <= 1000000; i++)
      s.write(i+"\n");
s.end()
var fs=require('fs'))
var s=fs.createWriteStream(“test.txt”);

对于(i=1;i我认为这可能是特定于环境的,您是在什么环境下编写的? 起初我以为这是为了一个网站,但这涉及到写文件,这让我很反感


否则,使用文件系统会很有趣,这取决于实现情况,我不应该责怪编程语言,但我真的不知道javascript如何在您的特定系统上处理文件IO,文件IO中的性能本身就是一门科学,可能和计算机科学本身一样古老。

发生这种情况是因为
for
cCycle是同步的,但
可写。write()
不是。例如,s.write创建100万个chuncks队列。这会导致超过100万个函数调用()要处理此队列。因此,
Writable.write
不是为小块而设计的。您可以使用
Writable.write
来获取有关它的更多信息。

它是一个被填满的缓冲区。每次写入都将返回
true
false
,具体取决于内核缓冲区的状态

如果您开始监听返回代码并使用事件,它至少会保持一致的速度

var fs = require ('fs') 

function runTest(stop) {
  var s = fs.createWriteStream("test.txt");
  var startTime = Date.now();
  var c = 1;
  function doIt() {
    while (++c <= stop) {
      if (!s.write(c+"\n")) {
        s.once('drain', doIt);
        return;
      }
    }

    s.end();
    var diffTime = Date.now() - startTime;
    console.log(stop+': took '+diffTime+'ms, per write: '+(diffTime/stop)+'ms')
  }

  doIt();
}

runTest(10000);
runTest(100000);
runTest(1000000);
runTest(10000000);
runTest(100000000);

如果您对node.js环境一点也不熟悉,那么您可能应该把这个问题放在一边。我可以确认这在我的Linux虚拟机上发生了:
0m2.372s
vs
1m0.039s
。这个数字太圆了,这让我觉得可能是写入流深处的超时。我将进一步研究它。另外,wh使用
strace
,在第一种情况下,它的速度明显减慢,降到
0m7.259s
,但在第二种情况下,它的速度相同,
1m6.462s
,这让我更加怀疑。数据的大小是否与退化的性能直接相关(如果是,大小是多少,以字节为单位)或者是
write
调用的数量?这很公平,但为什么一次调用与112050之间的差异会使处理时间从3秒增加到1分钟以上?@TonyBiondo,可能是任何东西……可能与IO链中某个东西的缓冲区大小有关。实验。正是因为如此,我将输出排队,然后y为每百万分之一项调用
write
,这大大加快了速度:)这些测试交错进行。第一次
runTest(10000)
点击
s.once('drain',doIt')
,下一个
运行测试(100000)
已经开始运行。您可以通过插入
console.log('Testing'+stop+'…')来验证这一点位于函数顶部。
var fs = require ('fs') 

function runTest(stop) {
  var s = fs.createWriteStream("test.txt");
  var startTime = Date.now();
  var c = 1;
  function doIt() {
    while (++c <= stop) {
      if (!s.write(c+"\n")) {
        s.once('drain', doIt);
        return;
      }
    }

    s.end();
    var diffTime = Date.now() - startTime;
    console.log(stop+': took '+diffTime+'ms, per write: '+(diffTime/stop)+'ms')
  }

  doIt();
}

runTest(10000);
runTest(100000);
runTest(1000000);
runTest(10000000);
runTest(100000000);
$ node test.js
10000: took 717ms, per write: 0.0717ms
100000: took 5818ms, per write: 0.05818ms
1000000: took 42902ms, per write: 0.042902ms
10000000: took 331583ms, per write: 0.0331583ms
100000000: took 2542195ms, per write: 0.02542195ms