Repository navigation
react-packager: Use Bluebird (or others) instead of Q as Promises library #361
Description
Activity
I think most bottleneck are transformation and filesystem. If you want to give it a go and report back numbers, I'll happily consider it :)
The benchmark isn't really relevant as it runs with N=10000 and (I assume) packager is always N=1 - if you run the benchmark with N=1 you will hopefully not see any difference between implementations as anything is fast for a small N.
Thanks for the clarification @petkaantonov
If we end up standardizing on Bluebird in React Native we'll switch the packager to it as well.I probably picked an irrelevant benchmark above depending on what it really tested, but I still think I identified a real performance bottleneck here...
I ran a quick test just on
DependencyGraphand got an interesting result as follows:Test Summary
Bluebird performed almost 2x faster 👊
- System Info
- MacBook Pro (Retina, 13-inch, Early 2015)
- 2.7 GHz Intel Core i5
- 16 GB 1867 MHz DDR3
You can find the test script and full result here.
DependencyGraph with Q (current code)
#ofRuns: 100 Average: 5016 ms Median: 4879.5 ms Minimum: 4079 ms Maximum: 7744 ms StdDev: 639.8 msDependencyGraph with Bluebird (modified code)
#ofRuns: 100 Average: 2742.3 ms Median: 2648 ms Minimum: 2043 ms Maximum: 5034 ms StdDev: 504.6 msNote that I only replaced
DependencyGraphmodule for this quick test. Imagine how much performance gain you can expect if all modules currently usingQmake a switch toBluebird. There are even (presumably) faster (less features) promise implementations such as es6-promise.I discovered this problem while trying to integrate with webpack. The solution I currently settled on uses
DependencyGraphto query internal dependencies to be able to resolvereact-nativemodules from thewebpackland. Each webpack build took annoyingly too long, that's how I started searching for an internal bottleneck.That's surprising that so many promises are being created that there is actually a difference. It would be interesting to know how many. The bluebird sequential benchmark creates 80000 promises with N=10000 and 8 promises with N=1, hence why you wouldn't see any difference with N=1.
@petkaantonov This particular case (
DependencyGraph) that I tested with hits the filesystem like crazy as it scans the entire file tree to extract dependencies information. The promises library is heavily utilized to glue IO and transformation operations.What's the best way to measure how many promises are created?
@pilwon In bluebird I have just ad hoc edited the promise constructor code by doing Promise.promisesCreated++ (Initialize it to 0 somewhere first) inside the constructor and then reading it out at the end of the benchmark.
Also results for 3.0 would be interesting too as it provides some significant performance improvements to Promise.all and promisify
@petkaantonov Is this the right place?
@pilwon Yes it is
46039 promises are created in each test run. 😱 😲 😒
Ok, that's shocking and my earlier point doesn't make sense any more.. I was expecting more like 10-100 promises being created
This awesome, thanks for digging into it.
fixed
- added a commit that references this issue
on Jan 26, 2017 - locked as resolved and limited conversation to collaborators
on May 29, 2018 - addedResolution: LockedThis issue was locked by the bot.This issue was locked by the bot.
on Jul 23, 2018
Q is very slow and eats so much memory compared to alternative Promises libraries as shown here.
Consider switching to Bluebird or something else to squeeze out performance for
react-packager.