TL;DR - incredibly slow!
I was working on some "framework" type code, where it often makes sense to provide wrappers where the framework accepts a user-defined callback. The sensible default is to accept an async callback since you don't know when the user might need to do any disk/network/etc calls which require an async wrapper.
The question arose of what the cost is of supporting async callbacks rather than synchronous ones. I assumed the overhead would not be huge, but thought it was worth validatating that assumption and, boy, was I wrong!
I ran both async and sync versions of a fairly trivial function. I did 10 runs where each run called the function 1,000,000 times and then ran this test in three different environments.
Each run called the sync function (callSync
), the async function with await (callAsync
),
and the sync function with await (callAwait
).
Average time for callSync: 0.630ms
Average time for callAwait: 1187.240ms
Average time for callAsync: 2835.600ms
node index.js
Average time for callSync: 0.589ms
Average time for callAwait: 39.519ms
Average time for callAsync: 83.566ms
bun run index.js
Average time for callSync: 0.706ms
Average time for callAwait: 75.163ms
Average time for callAsync: 154.645ms
I don't consider this code to be a great "benchmark" between the various platforms,
but the undeniable conclusion is that async
functions have a high overhead when used
in "hot" code paths and should be avoided if possible.
Most framework code is not called in a hot loop like this, so the overhead is nearly always
worth the flexibility, but this was not the result I was hoping for. It would be much
simpler to just use async
functions by default.