承诺并行和CPU

jbr*_*rnd 4 javascript parallel-processing node.js promise

我需要澄清一些关于Node.js,Promises,CPU和性能的内容.

为了设置上下文,我将讨论多次执行的异步处理(数据库查询)(在循环中),然后在所有异步之后执行其他操作.处理完成.

让我们从代码示例开始:

async function databaseQuery() {
    return await connection.query('SELECT * FROM example;');
}
Run Code Online (Sandbox Code Playgroud)

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

让我们使用并行Promises来实现这个目标:

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
Run Code Online (Sandbox Code Playgroud)

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

  • 本地计算机,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进程?

在此输入图像描述

代码中没有实现"多处理"代码(cluster例如使用).

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

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

sne*_*nek 5

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

您的数据库库,其他插件或Node.js核心中的错误内容可能由于各种原因创建其他线程.

这显示为多核利用率,因为(简化术语)CPU将在核心周围传递线程.

作为旁注,return await完全不需要,您可以从异步函数返回promise,它们将被解包,因为promise promise是一个平面映射操作.

[1] libuv处理I/O,例如从文件读取,制作tcp套接字和调度定时器.

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