I need to clarify something about Node.js, Promises, CPU and performance.
To set up a context, I will talk about an asynchronous processing (database query) executed multiple times (in a loop) and then do something else only after all async. processings are done.
Let's start with a code example :
async function databaseQuery() {
return await connection.query('SELECT * FROM example;');
}
I want to perform n times an async call (databaseQuery
function), and when these n executions are over, do something else.
Let's use parallels Promises to achieve this goal :
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
I tried an implemention of this code in two environnements :
- Local Machine, Windows 10 x64, Intel i7 6c/12t , 16g RAM
- Remote server (virtualized server @ OVH), Ubuntu 16.04, 1vCore, 6g RAM
Obviously, performance on the local machine are far away better than on the remote one (< 1 second vs. > 1 minute).
But I need some precisions on Why ?. I'm aware that physical materials are way better on the local machine.
Moreover, as Node.js is running on a single thread on a single core why the Windows resources monitor the Node.js process using 10 threads and 6 processors ?
There is no "multi-processing" code implemented in the code (using cluster
for example).
If I want to put this code in production, should I pay attention of the processor number of cores, or it is a Windows internal process management ?
Please help me clarify this situation, I really want to understand how does this work in the background, as it will help to choose right configuration to run this type of code.
I need to clarify something about Node.js, Promises, CPU and performance.
To set up a context, I will talk about an asynchronous processing (database query) executed multiple times (in a loop) and then do something else only after all async. processings are done.
Let's start with a code example :
async function databaseQuery() {
return await connection.query('SELECT * FROM example;');
}
I want to perform n times an async call (databaseQuery
function), and when these n executions are over, do something else.
Let's use parallels Promises to achieve this goal :
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
I tried an implemention of this code in two environnements :
- Local Machine, Windows 10 x64, Intel i7 6c/12t , 16g RAM
- Remote server (virtualized server @ OVH), Ubuntu 16.04, 1vCore, 6g RAM
Obviously, performance on the local machine are far away better than on the remote one (< 1 second vs. > 1 minute).
But I need some precisions on Why ?. I'm aware that physical materials are way better on the local machine.
Moreover, as Node.js is running on a single thread on a single core why the Windows resources monitor the Node.js process using 10 threads and 6 processors ?
There is no "multi-processing" code implemented in the code (using cluster
for example).
If I want to put this code in production, should I pay attention of the processor number of cores, or it is a Windows internal process management ?
Please help me clarify this situation, I really want to understand how does this work in the background, as it will help to choose right configuration to run this type of code.
Share Improve this question edited Jul 16, 2018 at 14:55 jbrtrnd asked Jul 16, 2018 at 12:52 jbrtrndjbrtrnd 3,8435 gold badges26 silver badges41 bronze badges 12-
1
promises = array.map(databaseQuery);
presumably? – Roamer-1888 Commented Jul 16, 2018 at 13:24 - maybe helpful for your future development netguru.co/blog/… – BraveButter Commented Jul 16, 2018 at 14:49
-
Your code run in a single thread (the Main Loop), but Node creates other threads in order to delegate them all its async I/O requests. It's possible that also the
connection.query
do something that creates some child process. What library is it? – Luca Rainone Commented Jul 16, 2018 at 15:02 - Every program is going to show a few other threads in the resource monitor because the operating system gives the program a few threads for munication purposes or something, I don't really know what they are used for tbh. Even a hello world program written in C will have these extra threads. Also like Luca Rainone said, Node also has a few threads it uses for I/O. But your application code is always on the main thread. The only thing Node gives you in terms of "concurrency" is switching context when a function is waiting for I/O to return. – user6713871 Commented Jul 16, 2018 at 15:06
- 1 @jbrtrnd the most time spend for database queries is not in node but in the DBMS, node will send the querie using a socket to the DMBS and receives the data through the socket. There is no need or advantage at this point using multible threads for nodejs because this can be done event based. – t.niese Commented Aug 26, 2018 at 18:04
1 Answer
Reset to default 8Node.js runs the JavaScript you put into it in a single thread, but it has many more threads performing various tasks for I/O and the microtask queue. At the time of me writing this answer, Node.js will always have at least 7 threads: 4 for the libuv event loop[1], 4 for running background tasks for V8[2], and 1 for scheduling delayed background tasks for V8.
Your DB library, other addons, or misc things in Node.js core may be creating additional threads for various reasons.
This shows up as multi-core utilization because (in simplified terms) CPUs will pass threads around cores.
As a side note, return await
is pletely unneeded, you can return promises from async functions and they will be unwrapped because promise resolution is a flat-map operation.
[1] libuv handles I/O, for example reading from files, making tcp sockets, and scheduling timers.
[2] V8 background tasks include running the garbage collector and optimizing code.