I have intense CPU consuming computations that need to be done and then written to file. I know that I can use promises to create parallelism in writing and reading files, since it is an I/O operation. But can I use promises to create parallelism in computations over promises even though there isn’t an asynchronous operation?
If I can’t use promises for this, what can I do so that this operation doesn’t block the thread?
For example, a random time consuming calculation to create raw data. And it is written to file like this.
This function takes 9-10ms to complete in my computer.
const fs = require('node:fs');
async function main() {
console.time('Write file');
let content = 'number,number,number,number,numbern';
function getRandomInt() {
return Math.floor((Math.random() + 1000) * 1000000000000000000000);
}
for(let i = 0; i<1400;i++){
content += `${getRandomInt() * getRandomInt()},${getRandomInt() * getRandomInt()},${getRandomInt() * getRandomInt()},${getRandomInt() * getRandomInt()},${getRandomInt() * getRandomInt()}n`;
}
fs.writeFile('./fakeData.csv', content, err => {
// file written successfully
console.log("File written successfully!");
console.timeEnd('Write file');
});
}
main();
So, I tried to speed up the process by dividing it to chunks in promises.
This function takes 7-8ms to complete.
const fs = require('node:fs');
async function main() {
console.time('Write file');
let content = 'number,number,number,number,numbern';
function getRandomInt() {
return Math.floor((Math.random() + 1000) * 1000000000000000000000);
}
const write200Line = new Promise((resolve,reject)=>{
let content = '';
for(let i = 0; i<200;i++){
content += `${getRandomInt() * getRandomInt()},${getRandomInt() * getRandomInt()},${getRandomInt() * getRandomInt()},${getRandomInt() * getRandomInt()},${getRandomInt() * getRandomInt()}n`;
}
resolve(content);
});
const values = await Promise.all([write200Line, write200Line, write200Line, write200Line, write200Line, write200Line, write200Line]);
values.forEach(val => {
content += val;
});
fs.writeFile('./fakeData.csv', content, err => {
// file written successfully
console.log("File written successfully!");
console.timeEnd('Write file');
});
}
main();
I couldn’t understand why it is faster, even though there is no asynchronous operation in the promises. I write to the file at the end of the function without any parallelism.
Although I see some improvement with this setup, contrary to my expectations, it doesn’t decrease the time when I divide it further like write100Line with more promises.
And why I see improvement when I divide it to 7 chunks rather than 1 for loop, but can’t see any improvement on 14 chunks.