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

我正在玩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() 

我尝试了使用不同的值,发现1-112050需要3秒,1-112051需要一分钟。 这突然下降是奇怪的。 python中的相同程序,或等效的shell脚本“seq 1 112051”在合理的时间(0-2秒)内运行。

请注意,这个node.js应用运行得更快:

 var fs = require('fs') , s = [] for (var i = 1; i <= 1000000; i++) s.push(i.toString()) s.push('') fs.writeFile('UIDs.txt', s.join('\n'), 'utf8') 

任何人都可以向我解释为什么node.js这样做,为什么dropoff是如此突然?

       

网上收集的解决方案 "为什么这个node.js循环在112050迭代之后缓慢运行?"

这是一个被填满的缓冲区。 每次写入将根据内核缓冲区的状态返回truefalse

如果你开始听返回代码并使用排水事件,它至less会在速度上保持一致。

 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 

发生这种情况是因为循环是同步的,但是Writable.write()不是。 举个例子,s.write创build了一百万个 chunck队列。 这导致超过一百万个函数调用( 如这样 )来处理这个队列。 所以, Writable.write不是为小块devise的。 您可以检查 Writable.write 来源以获取有关它的更多信息。

我相信这可能是环境特定的,你在什么情况下编码? 例如,最初我以为这是一个网站,但它涉及到写下文件,把我扔掉。

否则,使用文件系统的工作很有趣取决于实现,我不是一个责怪编程语言,但我真的不知道如何JavaScript对待你的特定系统上的文件IO,文件IO的性能本身是一门科学,可能和计算机科学本身一样古老。