首页 文章

NodeJS,承诺和表现

提问于
浏览
1

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

如果我的程序运行12次迭代,每次1.250.000 = 15.000.000次迭代 - 它需要亚马逊的专用服务器以下时间来处理:

r3.large:2个vCPU,6.5个ECU,15个GB内存 - > 123分钟4.8xlarge:36个vCPU,132个ECU,60个GB内存 - > 102分钟

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

start();

开始(){

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

函数2(); //按日期间隔迭代一个集合 - 其中包含按间隔分割的数据 . 这个函数实际上也是递归的 - 由于事实 - 多次运行数据(MAX 50-100次) - 由于间隔大小不同...
}
}

函数2(){

返回新的承诺{

for(var i = 0; i <1.250.000; i){
返回新的承诺{
功能3(); //这个函数简单地迭代所有可能的组合 - 并调用function3 - 所有给定的值/组合
}
}
}
}

功能3(){
return new Promise {//这个函数简单地根据给定的值/组合进行一些计算 - 然后将结果返回给function2 - 最后 - 决定哪个结果/组合是最好的...
}}

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

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

当我执行应用程序时,我使用内存选项如:

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

请告诉我你能做的每一件事 - 让我的节目更快!

谢谢大家 - 非常感谢!

1 回答

  • 7

    它最佳地工作但它根本不起作用 - 你没有给它任何机会 .

    在开发tco module时,我在Node中做了tail call优化,我注意到了一件奇怪的事情 . 它似乎泄漏了记忆,我不知道为什么 . 事实证明,这是因为在我用于测试以查看正在发生的事情的各个地方几乎没有 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();
    

    它也是这样 - 它将数字从 a 打印到 b 但是以100的串数打印,然后它会在事件循环结束时安排自己继续 .

    输出 $(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'

    Maximum resident set size (kbytes): 56404
    

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

    另见这些答案:

相关问题