Javascript Node.js移动占用大量CPU的任务

Javascript Node.js移动占用大量CPU的任务,javascript,node.js,performance,Javascript,Node.js,Performance,我有一个函数,它根据传递的参数自递归地调用它。这个函数在最后调用另一个函数,这可能会占用大量CPU,因为它处理一组N个对象,并执行大量的string操作。当N足够大时,会减慢应用程序的速度。使用计时器将字符串操作移动到事件循环中是行不通的,因为它仍然会减慢应用程序执行该循环后面的代码的速度。我曾想过使用child\u process生成另一个节点实例,但我认为这也不是一个好的解决方案,因为根据传递给第一个函数的配置,可以多次调用该函数,这意味着大量生成的node.js进程 下面是一个说明问题的代

我有一个函数,它根据传递的参数自递归地调用它。这个函数在最后调用另一个函数,这可能会占用大量CPU,因为它处理一组N个对象,并执行大量的
string
操作。当N足够大时,会减慢应用程序的速度。使用计时器将
字符串
操作移动到事件循环中是行不通的,因为它仍然会减慢应用程序执行该循环后面的代码的速度。我曾想过使用
child\u process
生成另一个节点实例,但我认为这也不是一个好的解决方案,因为根据传递给第一个函数的配置,可以多次调用该函数,这意味着大量生成的node.js进程

下面是一个说明问题的代码示例:

function Fun(opts) {
    // depending on opts we call HeavyCPU alot
    while (...) {
        var set = ...;
        HeavyCPU(set)
    }
}

function HEAVYCPU(var set) {
    // Heavy CPU task - string manipulations
}

module.exports = Fun;
如果我以这种方式生成子进程:

// fun.js
var cp = require('child_process');
function Fun(opts) {
    // depending on opts we call HeavyCPU alot
    while (...) {
        var set = ...;
        var child = cp.fork('./heavycpu', set);
    }
}

module.exports = Fun;

// heavycpu.js
function HEAVYCPU(var set) {
    // Heavy CPU task - string manipulations
}
根据依赖于
opts
的while语句,我仍然可以生成大量进程


在这种情况下我能做什么?

为了防止子进程的多次生成,您可以格式化参数并在
HEAVYCPU
中调用while进程(您的子任务)

fun.js

var cp = require('child_process');
function Fun(opts) {
    var arguments = processOptions(opts) //processOptions is just an example
    var child = cp.fork('./heavycpu', arguments );
}

module.exports = Fun;
heavycpu.js

function HEAVYCPU(var set) {
    while(...) {
      //Here goes the actual processing code
    }
}
如果不想将
HEAVYCPU
代码与迭代参数混用,可以创建一个包装函数(然后在子进程中调用),该函数处理提供的参数,然后调用
HEAVYCPU

您还可以将每个参数发送到流程:

child_process.fork()方法是child_process.spawn()的特例,专门用于生成新的Node.js进程。与child_process.spawn()类似,将返回一个ChildProcess对象。返回的ChildProcess将内置一个额外的通信通道,允许在父进程和子进程之间来回传递消息。有关详细信息,请参见child.send()


为了防止子进程的多次生成,您可以格式化参数并在
HEAVYCPU
中调用while进程(您的子任务)

fun.js

var cp = require('child_process');
function Fun(opts) {
    var arguments = processOptions(opts) //processOptions is just an example
    var child = cp.fork('./heavycpu', arguments );
}

module.exports = Fun;
heavycpu.js

function HEAVYCPU(var set) {
    while(...) {
      //Here goes the actual processing code
    }
}
如果不想将
HEAVYCPU
代码与迭代参数混用,可以创建一个包装函数(然后在子进程中调用),该函数处理提供的参数,然后调用
HEAVYCPU

您还可以将每个参数发送到流程:

child_process.fork()方法是child_process.spawn()的特例,专门用于生成新的Node.js进程。与child_process.spawn()类似,将返回一个ChildProcess对象。返回的ChildProcess将内置一个额外的通信通道,允许在父进程和子进程之间来回传递消息。有关详细信息,请参见child.send()


为什么不生成另一个子进程,然后在其中调用
HEAVYCPU
,而不是在其中生成进程。@CodeSpirit但我可能会调用
HEAVYCPU
很多时间取决于
opts
,这可能会让我生成很多子进程我的意思是:启动进程,执行
HEAVYCPU
调用,结束进程。@CodeSpirit我不知道我怎么会以这种方式结束大量派生进程。我编辑了这个问题是为了向您展示。@Jorayen通常,当有许多计算繁重的任务需要执行时,您无法控制,最好使用某种队列管理器来处理这些任务,并且根据您的机器的能力,您可以运行有限数量的N,并将其余任务排队,直到完成优先级。这不是特定于
节点的
,而是几乎所有的系统,除非有人有任何其他想法。为什么不生成另一个子进程,然后在其中调用
HEAVYCPU
,而不是在其中生成进程。@CodeSpirit,但我可能会根据
opts
,大量时间调用
HEAVYCPU
,这可能会让我产生很多子进程。我的意思是:开始进程,执行
HEAVYCPU
调用,结束进程。@CodeSpirit我不知道我怎么会以这种方式产生很多进程。我编辑了这个问题是为了向您展示。@Jorayen通常,当有许多计算繁重的任务需要执行时,您无法控制,最好使用某种队列管理器来处理这些任务,并且根据您的机器的能力,您可以运行有限数量的N,并将其余任务排队,直到完成优先级。这对
节点
不是特别的,但对几乎所有的系统来说都是如此,除非有人有其他想法。那么,你能推荐一个轻量级的工作队列模块吗?它可以让我启动node.js进程,这些独立的函数像我的
HEAVYCPU
,而无需将其分离到不同的模块?我还想指出这一点
Fun
HEAVYCPU
是同一类的函数
HEAVYCPU
从此类实例发出事件,因此将其分离到不同的模块将不好,因为发出的事件预期将从原始类实例发出。此外,为该函数生成一个新进程也不行,因为它将失去实例的上下文,也无法发出事件。那么,您是否可以推荐一个轻量级工作队列模块,让我可以启动独立函数的Node.js进程,如my
HEAVYCPU
,而不将其分离为不同的模块?我还想指出
Fun
HEAVYCPU
是同一类的函数
HEAVYCPU
从此类实例发出事件,因此将其分离到不同的模块将不好,因为发出的事件预期将从原始类实例发出。另外,为该函数生成一个新进程也不行,因为它将丢失实例的上下文,并且也无法发出事件。