Skip to content

Instantly share code, notes, and snippets.

@andvgal
Created September 25, 2018 15:44
Show Gist options
  • Save andvgal/14e745405c3cb7d14bd91ab0530ce8ca to your computer and use it in GitHub Desktop.
Save andvgal/14e745405c3cb7d14bd91ab0530ce8ca to your computer and use it in GitHub Desktop.
Node.js async/await issue reveal - blocked event loop
const TEST_TIMEOUT = 1;
(async () => {
const raw = () => {
let count = 0;
const start = process.hrtime();
while (process.hrtime(start)[0] < TEST_TIMEOUT) {
for(let j = 0; j < 128; ++j) {
++count;
}
}
return count;
};
const async_f = async () => {
let count = 0;
const start = process.hrtime();
const step = async () => {};
while (process.hrtime(start)[0] < TEST_TIMEOUT) {
for(let j = 0; j < 128; ++j) {
await step();
++count;
}
}
return count;
};
const async_double = async () => {
const start = process.hrtime();
const f = async (start) => {
let count = 0;
const step = async () => {
++count;
};
while (process.hrtime(start)[0] < TEST_TIMEOUT) {
for(let j = 0; j < 128; ++j) {
await step();
}
}
return count;
};
return Promise.all([
f(start),
f(start)
]);
};
const event_loop = () => new Promise(resolve => {
let count = 0;
const start = process.hrtime();
const fire = () => {
++count;
};
const iter = () => {
++count;
if (process.hrtime(start)[0] >= TEST_TIMEOUT) {
resolve(count);
return;
}
for(let j = 0; j < 128; ++j) {
setImmediate(fire);
}
setImmediate(iter);
};
setImmediate(iter);
});
const async_event_loop = async () => {
const start = process.hrtime();
const f = async (start) => {
let count = 0;
const step = async () => {
++count;
};
while (process.hrtime(start)[0] < TEST_TIMEOUT) {
for(let j = 0; j < 128; ++j) {
await step();
}
}
return count;
};
const el = (start) => new Promise(resolve => {
let count = 0;
const fire = () => {
++count;
};
const iter = () => {
++count;
if (process.hrtime(start)[0] >= TEST_TIMEOUT) {
resolve(count);
return;
}
for(let j = 0; j < 128; ++j) {
setImmediate(fire);
}
setImmediate(iter);
};
setImmediate(iter);
});
return Promise.all([
f(start),
el(start)
]);
};
const raw_res = raw();
const async_one_res = await async_f();
const async_double_res = await async_double();
const event_loop_res = await event_loop();
const async_event_loop_res = await async_event_loop();
console.log(`Raw count: ${raw_res}`);
console.log(`Async count: ${async_one_res}`);
console.log(`Async parallel count: ${async_double_res}`);
console.log(`Event loop: ${event_loop_res}`);
console.log(`Async + Event loop: ${async_event_loop_res}`);
console.log(`END`);
})();
@andvgal
Copy link
Author

andvgal commented Sep 25, 2018

Results v10:

$ nodeVer=10 cte node async_await.js
Exec: ~/.nvm/versions/node/v10.11.0/bin/node async_await.js
Raw count: 27436800
Async count: 3477504
Async parallel count: 2026496,2026496
Event loop: 5846797
Async + Event loop: 3890688,1
END

Results v8:

$ nodeVer=8 cte node async_await.js
Exec: ~/.nvm/versions/node/v8.12.0/bin/node async_await.js
Raw count: 27528960
Async count: 2431232
Async parallel count: 1285504,1285504
Event loop: 918352
Async + Event loop: 2548352,1
END

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment