I know how to write concurrency code.
Async, multithreading, multiprocessing.
But I almost never use them.
My code defaults to being synchronous. It's easy and comfy.

The only problem? They are stupidly slow.
I had to generate a bunch of PDFs.
This is the first implementation:
let nextIndex = 0;
while (true) {
const file = files[nextIndex++];
if (!file) return;
// spawns a headless browser
await generatePdf(file);
}
Basically, just generate the PDFs one by one.

This works.
But the problem is I need to generate around a hundred PDFs, and each generation takes 2 seconds.
It takes 2 x 100 = 200 seconds, or ~3 minutes.
It's just way too slow. (I have to run this program many times.)
I had to improve this.
But how?
A conversation in an interview a few years ago came up. The guy was commenting on my code.
"You know what's the problem with your code?"
"Better comments or better variable names?"
"No, you're not using async."

Going back to this. It seems like I'm using async because "generatePdf" is an async function.
let nextIndex = 0;
while (true) {
const file = files[nextIndex++];
if (!file) return;
await generatePdf(file);
}But the code is not using concurrency efficiently.
Why would I run these tasks one by one while they can run in parallel?
It's like the question of if it takes you 5 minutes to cook one steak, how long does it take to cook 10? The answer is still 5 minutes because you can cook the steaks together.
So I changed my implementation:
// performance doesn't improve past 30
const concurrency = 30;
let nextIndex = 0;
// Create async tasks based on max concurrency
const workers = Array.from(
{ length: Math.min(concurrency, files.length) },
async () => {
while (true) {
const file = files[nextIndex++];
if (!file) return;
// spawns a headless browser
await generatePdf(file);
}
}
);
// Promise.allSettled allows generatePdf to runs in parallel
const results = await Promise.allSettled(workers);
const failure = results.find((result) => result.status === "rejected");
);
Instead of generating the files one by one, I generate 30 at the same time.

The time to run the program goes from 200 seconds to ~10 seconds.
A 20x improvement!
Concurrency, when used right, can drastically improve your program's efficiency.
- Fee from Anime Coders
