NodeJS,承诺和性能

我的问题是关于我的NodeJS应用程序的性能...

如果我的程序运行12次迭代,每次迭代次数为1.250.000次= 15.000.000次迭代,则需要在亚马逊下面的专用服务器进行处理:

r3.large:2个vCPU,6.5个ECU,15 GB内存 - > 123分钟

4.8x大容量:36个vCPU,132个ECU,60GB内存 - > 102分钟

我有一些代码similair下面的代码...

start();

start(){

  for(var i=0; i<12; i++){

      function2();    // Iterates over a collection - which contains data split up in intervals - by date intervals. This function is actually also recursive - due to the fact - that is run through the data many time (MAX 50-100 times) - due to different intervals sizes...
    }
}

function2(){

  return new Promise{

    for(var i=0; i<1.250.000; i++){       
         return new Promise{      
            function3();      // This function simple iterate through all possible combinations - and call function3 - with all given values/combinations
         }
      }   
   } 
}


function3(){
   return new Promise{ // This function simple make some calculations based on the given values/combination - and then return the result to function2 - which in the end - decides which result/combination was the best...
}}

这相当于0.411毫秒/ 441微秒的迭代!

当我查看任务栏中的性能和内存使用情况时...... CPU没有以100%运行 - 但更像是50%......整个时间? 内存使用开始非常低 - 但KEEPS以GB的速度增长 - 每过一分钟,直到完成该过程 - 但是(分配的)内存首先在Windows CMD中按CTRL + C时释放...所以它像NodeJS垃圾回收并不是最佳工作 - 或者可能是它简单的代码设计...

当我执行应用程序我使用内存选择如下:

节点--max-old-space-size =“50000”server.js

请告诉我你可以做的每件事 - 让我的程序更快!

谢谢大家 - 非常感谢!


并不是垃圾收集器不能最佳地工作,但它根本不起作用 - 你不会给它任何机会。

当开发在Node中进行尾部呼叫优化的tco模块时,我注意到一件奇怪的事情。 它似乎泄漏了记忆,我不知道为什么。 事实证明,这是因为在我用于测试的各个地方调用了很少的console.log()调用来查看发生了什么,因为看到递归调用数百万个级别深度的结果需要一些时间,所以我希望看到一些内容正在做。

你的例子与此非常相似。

请记住,Node是单线程的。 当你的计算运行时,没有其他东西可以 - 包括GC。 你的代码是完全同步和阻塞的 - 尽管它以阻塞的方式产生了数百万个承诺。 它阻塞,因为它永远不会到达事件循环。

考虑这个例子:

var a = 0, b = 10000000;

function numbers() {
  while (a < b) {
    console.log("Number " + a++);
  }
}

numbers();

这很简单 - 你想打印1000万个数字。 但是当你运行它时,它的行为非常奇怪 - 例如它打印数字到某个点,然后停止几秒钟,然后它继续前进,或者如果你使用交换,可能会开始垃圾,或者可能给你这个错误在看到8486号码之后我刚好看到:

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory
Aborted

这里发生的事情是,主线程在同步循环中被阻塞,它在创建对象时保持不变,但GC没有机会释放它们。

对于这样长时间运行的任务,您需要将您的工作分开,偶尔进入事件循环。

以下是你如何解决这个问题:

var a = 0, b = 10000000;

function numbers() {
  var i = 0;
  while (a < b && i++ < 100) {
    console.log("Number " + a++);
  }
  if (a < b) setImmediate(numbers);
}

numbers();

它也是这样做的 - 它打印从ab数字,但是以100为一组,然后它自己安排在事件循环结束时继续。

$(which time) -v node numbers1.js 2>&1 | egrep 'Maximum resident|FATAL' $(which time) -v node numbers1.js 2>&1 | egrep 'Maximum resident|FATAL'

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory
    Maximum resident set size (kbytes): 1495968

它使用了1.5GB的内存并崩溃。

$(which time) -v node numbers2.js 2>&1 | egrep 'Maximum resident|FATAL' $(which time) -v node numbers2.js 2>&1 | egrep 'Maximum resident|FATAL'

    Maximum resident set size (kbytes): 56404

它使用了56MB的内存并完成。

另请参阅以下答案:

  • 如何在Express请求处理程序中编写非阻塞异步函数
  • 如果当前请求有巨大的计算,node.js服务器如何服务下一个请求?
  • nodejs中超出最大调用堆栈大小
  • 节点; Q承诺延迟
  • 如何避免jimp阻止代码node.js
  • 链接地址: http://www.djcxy.com/p/55373.html

    上一篇: NodeJS, Promises and performance

    下一篇: Implement promises pattern