承诺并行性和CPU

时间:2018-07-16 12:52:13

标签: javascript node.js parallel-processing promise

我需要澄清一些有关Node.js,Promises,CPU和性能的信息。

要设置上下文,我将讨论多次(循环)执行一次异步处理(数据库查询),然后仅在全部异步后再执行其他操作。处理完成。

让我们从一个代码示例开始:

async function databaseQuery() {
    return await connection.query('SELECT * FROM example;');
}

我想执行一次 n 次异步调用(databaseQuery函数),并且当这些 n 执行结束时,执行其他操作。

让我们使用并行 Promise 实现这一目标:

const array = [...]; // Assuming this array is full of whatever

const promises = array.map(async (item) => {
    return await databaseQuery();
});

await Promise.all(promise);

// Ok now I'm sure all async calls are done

我尝试在两个环境中实现此代码:

  • 本地计算机,Windows 10 x64,Intel i7 6c / 12t,16g RAM
  • 远程服务器(虚拟服务器@ OVH),Ubuntu 16.04、1vCore,6g RAM

很明显,本地计算机的性能要比远程计算机好得多(<1秒vs.> 1分钟)。

但是我需要关于为什么?的一些精度。我知道物理材料在本地计算机上会更好。

此外,由于Node.js在单个内核上的单个线程上运行,为什么Windows资源使用10个线程和6个处理器监视Node.js进程?

enter image description here

该代码中没有实现“多处理”代码(例如,使用cluster)。

如果我想将此代码投入生产,我应该注意处理器的内核数,还是Windows内部进程管理?

请帮助我澄清这种情况,我真的想了解它在后台的工作方式,因为这将有助于选择正确的配置来运行这种类型的代码。

1 个答案:

答案 0 :(得分:5)

Node.js在单个线程中运行您放入其中的JavaScript,但是它有更多线程来执行I / O和微任务队列的各种任务。在我撰写此答案时,Node.js将始终至少具有7个线程:4个用于libuv事件循环[1],4个用于运行V8的后台任务[2],以及1个用于调度V8的延迟后台任务

由于各种原因,您的数据库库,其他插件或Node.js核心中的杂项可能正在创建其他线程。

这显示为多核利用率,因为(简单来说)CPU将在核心周围传递线程。

作为return await is completely unneeded的补充说明,您可以从异步函数返回诺言,由于诺言解析是一种平面映射操作,它们将被取消包装。

[1] libuv处理I / O,例如从文件读取,建立tcp套接字和调度计时器。

[2] V8后台任务包括运行垃圾收集器和优化代码。