【问题标题】:Multiple embedded loops in NodeJSNodeJS 中的多个嵌入式循环
【发布时间】:2016-07-09 09:09:57
【问题描述】:

我喜欢执行以下代码...但正如您所见 - 它需要 100 亿次循环!所以我想知道 - 你们会建议什么让它旋转得更快?

原因 - 我需要喜欢“蛮力”以获得最佳结果 - 是因为最内在的方法对一些历史数据进行了一些复杂的计算 - 来自数据库的大约 700 万行......所有这一切 - 是找到给定参数的最佳“设置”...这会产生最好的结果...

var a = 0.1;

while(a <= 10) // 100
{
    var b = 0.1;

    while(b <= 10) // 100
    {
        var c = 0.1;

        while(c <= 10) // 100
        {
            var d = 0.1;

            while(d <= 10) // 100
            {
                var e = 1;

                while(e <= 10) // 10
                {
                    var f = 1;

                    while(f <= 10) // 10 10.000.000.000
                    {
                        // Call at method which use all parameters and return the result of a given calculation
                        //doSomeThing(a,b,c,d,e,f);
                        f += 1;
                    }
                    e += 1;
                }
                d += 0.1;
            }
            c += 0.1;
        }
        b += 0.1;
    }
    a += 0.1;
}

【问题讨论】:

  • 如果你想尝试100亿个组合,那么你需要100亿个循环,没有变通办法,只能尝试更少的组合(即基于之前的doSomething结果你知道有些值不会好或有更广泛的结果)。如果 doSomething 方法不太难计算并且您只是不时运行它,个人 PC 也可以计算 100 亿次循环。
  • 1. NodeJS 的设计是异步的——因此许多多个调用将同时实例化到内部方法......但它仍然只会在一个单一的步骤中运行——我如何同时通过 100 个线程运行代码?简单地加快进程?顺便说一句 - 我需要一直运行这段代码 - 不断了解最佳“设置”是什么样的......因为历史数据也会从一分钟到下一分钟变化......
  • 这将占用大量 CPU...您可以使用 Promise(使用像 Bluebird 这样的库),但考虑到您的代码(尤其是对 doSomething(a,b,c,d,e,f) 的调用),您必须对其进行大幅更改.
  • 不确定您是否注意到(可能是复制粘贴错误),但那里有 6 个无限循环。将 a,b,c,d,e,f 的增量从内部切换到外部将修复它。
  • 你是对的 - 哈哈......我刚刚解决了这个问题 - 谢谢 ;-)

标签: javascript node.js performance asynchronous while-loop


【解决方案1】:

使用核心集群模块将循环分成更小的块并分叉进程,在一个分叉中处理每个更小的块。分叉将在单独的线程上运行,更好地利用 CPU。

https://nodejs.org/api/cluster.html#cluster_how_it_works

更新。好的,不要使用集群。请改用线程模块 - 它会容易得多。 https://www.npmjs.com/package/threads ...

var cores = require('os').cpus().length;
var Pool = require('threads').Pool; 
var pool = new Pool(cores);

var doSomeThing = pool.run(function(data,done){
    var result = data.a * data.b * data.c * data.d * data.e * data.f;
    done(result,data);
})


var a = 0.1;
var b = 0.1;
var c = 0.1;
var d = 0.1;
var e = 0.1;
var f = 0.1;


while(a <= 10) // 100 loops
{
    while(b <= 10) // 100 loops
    {
        while(c <= 10) // 100 loops
        {
            while(d <= 10) // 100 loops
            {
                while(e <= 10) // 10 loops
                {
                    while(f <= 10) // 10 loops
                    {
                        // Call at method which use all parameters and return the result of a given calculation
                        doSomeThing.send({a:a,b:b,c:c,d:d,e:e,f:f});
                        f += 0.1;
                    }
                    e += 0.1;
                }
                d += 0.1;
            }
            c += 0.1;
        }
        b += 1;
    }
    a += 1;
}

pool
  .on('error', function(job, error) {
    console.error('Job errored:', job);
  })
  .on('finished', function() {
    console.log('Everything done, shutting down the thread pool.');
    pool.killAll();
  });

【讨论】:

  • 如何将循环分成更小的部分?除此之外 - 我不需要更改我当前的代码 - 只需在我的 NodeJS 应用程序中添加和使用集群模块?然后每件事都会自动扩展并执行到最大值 - 通过使用最大数量的核心/线程?
  • @PabloDK 抱歉,这并不容易 :) 如果不重组代码,您将无法获得并行性的好处。等我有时间我会做一个快速演示。
  • 非常感谢 :-) 我是 NodeJS 的新手……我已经习惯了 .NET……但是制作(NodeJS)应用程序不应该那么复杂。多线程?
  • 其实,node.js 应用很难多线程! Node 基于事件 IO 模型,一般不应用于 CPU 密集型应用程序。当需要确实出现时,有一些方法可以做到(集群就是其中之一),但它们通常会让人不舒服,因为将线程与事件混合起来很难调试。
  • IO 模型与否 - 我认为超过 1 个线程很难调试 :-D 我的问题很简单 - 我不需要任何调试......我只是想执行我的方法/all 100 亿组合 - 以最快的方式......“仅此而已”......为了好玩 - 我只是用 6 个循环测试了上面的代码 - 但内部没有方法(耗时) - NodeJS 运行时环境是能够完成单次运行 - 所有 100 亿个组合......在我的 DELL XPS 13 - i7 笔记本电脑上在 34 秒内......令人印象深刻 - 与人脑相比,个人电脑可以处理什么......哈哈
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 1970-01-01
  • 2016-07-12
  • 2016-10-16
  • 2015-10-15
相关资源
最近更新 更多