perf: uses setImmediate() implementation from tiny-set-immediate
This PR changes the task scheduler to use an externally-provided macrotask scheduling function and defaults to using the setImmediate() implementation from tiny-set-immediate.
This is done to work around performance issues discovered in https://github.com/comunica/comunica/discussions/1552 and ultimately traced back to the enormous difference between setImmediate(), which is only available is Node.js-like environments, and setTimeout(fn, 0), which is what the in-house scheduleMacrotask function would fallback to prior to this change. The former is roughly 90x faster than the latter.
Are you seeing any (negative) impact when running the perf script?
From main:
20,000,000 elems 20 maps 3672.3449579999997
20,000,000 elems 20 maps 20 filter 2590.885416
100,000 iterators each with 5 maps and 100 elements 2878.7446660000005
From this PR:
20,000,000 elems 20 maps 3685.9225420000002
20,000,000 elems 20 maps 20 filter 2610.698125000001
100,000 iterators each with 5 maps and 100 elements 2886.2840000000006
@RubenVerborgh I couldn't find a way to spy on tiny-set-immediate's exports directly so I explicitly split the tests into two different sub-suites: one for the no-op spy, whose callback must be invoked manually, and one for a spy on tiny-set-immediate's setImmediate(), in which the callback is invoked automatically and thus the numerical checks are postponed via setImmediate() itself.
@rubensworks @RubenVerborgh just checkin in on this PR. I have not addressed all of the comments above as I wasn't able to find a way to spy on tiny-set-immediate's exports, hence the idea of splitting into two sub-suites (see previous comment).
Insofar as I remember this should be good to go, though perhaps it'd be worth adding an explicit mention to tiny-set-immediate in README.md to inform downstream users about the performance differences and why it would be a good idea to use it.
No pressure, as always. Over the next few weeks I'll probably experiment with using asynciterator for a major refactor and this morning it dawned on me that I hadn't followed up on this.