├── .gitignore ├── README.md ├── bench ├── build └── generators-tj-co.js /.gitignore: -------------------------------------------------------------------------------- 1 | deps 2 | node 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Which is the fastest Node.js async pattern? 2 | 3 | The asynchronous processing of Node.js becomes more and more convenient, and at the same time faster, as the version is upgraded. However, its convenience and speed have a trade-off. In this repository, to what degree a trade-off occurs in each environment of Node.js is visualized using the [DoxBee benchmark](https://github.com/petkaantonov/bluebird/tree/master/benchmark). This will be a great aid to your development. 4 | 5 | ## TL;DR 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 |
Node.JSV8async typetime(ms)memory(MB)
v6.16.05.1.281.111callback11024.49
async/await731146.29
v8.15.06.2.414.75callback14428.30
async/await44791.31
v10.15.06.8.275.32-node.45callback15325.84
async/await33366.56
v11.0.0-pre7.3.0-node.5 (candidate)callback16623.62
async/await27456.10
68 | 69 | 70 | ## Node.JS 11.0.0-pre / V8 7.3.0-node.5 (candidate) 71 | 72 | ``` 73 | file time(ms) memory(MB) 74 | callbacks-baseline.js 147 24.85 75 | callbacks-suguru03-neo-async-waterfall.js 195 43.86 76 | callbacks-caolan-async-waterfall.js 209 46.39 77 | promises-bluebird-generator.js 236 34.35 78 | promises-bluebird.js 252 49.63 79 | promises-native-async-await.js 277 55.62 80 | generators-tj-co.js 295 60.26 81 | promises-ecmascript6-native.js 307 69.44 82 | promises-lvivski-davy.js 309 90.01 83 | promises-cujojs-when.js 365 55.25 84 | promises-then-promise.js 407 72.75 85 | promises-tildeio-rsvp.js 444 86.48 86 | promises-dfilatov-vow.js 588 117.81 87 | promises-calvinmetcalf-lie.js 589 103.96 88 | streamline-generators.js 656 80.00 89 | promises-obvious-kew.js 686 59.55 90 | promises-medikoo-deferred.js 860 111.28 91 | observables-pozadi-kefir.js 861 137.10 92 | streamline-callbacks.js 995 96.79 93 | observables-Reactive-Extensions-RxJS.js 1262 171.39 94 | promises-kriskowal-q.js 3509 292.23 95 | observables-caolan-highland.js 3848 473.17 96 | observables-baconjs-bacon.js.js 6555 652.24 97 | 98 | Platform info: 99 | Linux 4.4.0-87-generic x64 100 | Node.JS 11.0.0-pre 101 | V8 7.3.0-node.5 (candidate) 102 | Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz × 2 103 | ``` 104 | 105 | ## Node.JS 10.15.0 / V8 6.8.275.32-node.45 106 | 107 | ``` 108 | file time(ms) memory(MB) 109 | callbacks-baseline.js 153 25.84 110 | promises-bluebird-generator.js 202 36.63 111 | callbacks-suguru03-neo-async-waterfall.js 207 40.98 112 | callbacks-caolan-async-waterfall.js 224 46.12 113 | promises-bluebird.js 285 46.12 114 | promises-lvivski-davy.js 328 87.42 115 | promises-native-async-await.js 333 66.56 116 | promises-then-promise.js 334 64.21 117 | promises-cujojs-when.js 350 63.90 118 | promises-ecmascript6-native.js 351 80.83 119 | generators-tj-co.js 366 73.55 120 | promises-tildeio-rsvp.js 408 81.48 121 | promises-calvinmetcalf-lie.js 506 128.74 122 | promises-dfilatov-vow.js 679 111.44 123 | streamline-generators.js 705 84.40 124 | promises-obvious-kew.js 715 83.38 125 | promises-medikoo-deferred.js 810 114.87 126 | observables-pozadi-kefir.js 858 149.16 127 | streamline-callbacks.js 1113 113.45 128 | observables-Reactive-Extensions-RxJS.js 1350 177.45 129 | observables-caolan-highland.js 3752 461.60 130 | promises-kriskowal-q.js 4123 319.90 131 | observables-baconjs-bacon.js.js 5886 535.86 132 | 133 | Platform info: 134 | Linux 4.4.0-87-generic x64 135 | Node.JS 10.15.0 136 | V8 6.8.275.32-node.45 137 | Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz × 2 138 | ``` 139 | 140 | ## Node.JS 8.15.0 / V8 6.2.414.75 141 | 142 | ``` 143 | file time(ms) memory(MB) 144 | callbacks-baseline.js 144 28.30 145 | callbacks-caolan-async-waterfall.js 231 48.38 146 | promises-bluebird.js 242 47.80 147 | promises-bluebird-generator.js 242 40.97 148 | callbacks-suguru03-neo-async-waterfall.js 279 48.63 149 | promises-cujojs-when.js 359 64.32 150 | promises-lvivski-davy.js 389 90.06 151 | promises-ecmascript6-native.js 421 92.20 152 | promises-native-async-await.js 447 91.31 153 | promises-then-promise.js 462 72.48 154 | generators-tj-co.js 490 86.15 155 | promises-tildeio-rsvp.js 492 84.33 156 | promises-dfilatov-vow.js 748 135.25 157 | promises-obvious-kew.js 826 121.65 158 | promises-calvinmetcalf-lie.js 843 161.94 159 | streamline-generators.js 870 79.19 160 | promises-medikoo-deferred.js 1027 108.76 161 | observables-pozadi-kefir.js 1158 142.53 162 | streamline-callbacks.js 1416 96.54 163 | observables-Reactive-Extensions-RxJS.js 2190 173.97 164 | promises-kriskowal-q.js 8172 292.39 165 | observables-caolan-highland.js 10936 516.39 166 | observables-baconjs-bacon.js.js 24106 832.02 167 | 168 | Platform info: 169 | Linux 4.4.0-87-generic x64 170 | Node.JS 8.15.0 171 | V8 6.2.414.75 172 | Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz × 2 173 | ``` 174 | 175 | ## Node.JS 6.16.0 / V8 5.1.281.111 176 | 177 | ``` 178 | file time(ms) memory(MB) 179 | callbacks-baseline.js 110 24.49 180 | callbacks-suguru03-neo-async-waterfall.js 177 40.06 181 | callbacks-caolan-async-waterfall.js 180 45.30 182 | promises-bluebird-generator.js 191 38.87 183 | promises-bluebird.js 228 47.09 184 | promises-cujojs-when.js 262 64.25 185 | promises-then-promise.js 268 66.41 186 | promises-lvivski-davy.js 307 85.16 187 | promises-tildeio-rsvp.js 323 88.00 188 | promises-dfilatov-vow.js 576 119.18 189 | promises-calvinmetcalf-lie.js 586 161.76 190 | generators-tj-co.js 731 146.29 191 | promises-obvious-kew.js 810 110.66 192 | promises-ecmascript6-native.js 874 144.22 193 | promises-medikoo-deferred.js 1264 145.03 194 | observables-Reactive-Extensions-RxJS.js 1434 250.27 195 | streamline-generators.js 1467 121.52 196 | streamline-callbacks.js 2322 209.94 197 | promises-kriskowal-q.js 7943 453.51 198 | observables-baconjs-bacon.js.js 16689 825.02 199 | observables-pozadi-kefir.js 34186 154.47 200 | observables-caolan-highland.js 109155 493.84 201 | promises-native-async-await.js OOM OOM 202 | 203 | Platform info: 204 | Linux 4.4.0-87-generic x64 205 | Node.JS 6.16.0 206 | V8 5.1.281.111 207 | Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz × 2 208 | ``` 209 | 210 | 211 | - https://v8.dev/blog/fast-async 212 | - https://github.com/petkaantonov/bluebird/tree/master/benchmark 213 | - https://spion.github.io/posts/analysis-generators-and-other-async-patterns-node.html 214 | -------------------------------------------------------------------------------- /bench: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu -o pipefail 4 | cwd=$(cd $(dirname $0) && pwd) 5 | 6 | nodelist=$(cat ${cwd}/node/nodelist) 7 | cd ${cwd}/deps/bluebird 8 | 9 | export NODE_ENV=production 10 | root=${cwd}/deps/bluebird/benchmark 11 | 12 | if [ "$1" = "sequential" ]; then 13 | echo "Doxbee sequential" 14 | 15 | benchpath=${root}/doxbee-sequential 16 | 17 | bench+=(${benchpath}/callbacks-baseline.js) 18 | bench+=(${benchpath}/callbacks-caolan-async-waterfall.js) 19 | bench+=(${benchpath}/promises-bluebird.js) 20 | bench+=(${benchpath}/generators-tj-co.js) 21 | bench+=(${benchpath}/promises-bluebird-generator.js) 22 | bench+=(${benchpath}/promises-then-promise.js) 23 | bench+=(${benchpath}/promises-native-async-await.js) 24 | 25 | for node in ${nodelist[@]}; do 26 | ${node} ${root}/performance.js --n 10000 --t 1 ${bench[@]} --harmony 27 | done 28 | elif [ "$1" = "parallel" ]; then 29 | echo "Madeup parallel" 30 | 31 | benchpath=${root}/madeup-parallel 32 | 33 | bench+=(${benchpath}/callbacks-baseline.js) 34 | bench+=(${benchpath}/callbacks-caolan-async-parallel.js) 35 | bench+=(${benchpath}/promises-bluebird.js) 36 | bench+=(${benchpath}/generators-tj-co.js) 37 | bench+=(${benchpath}/promises-bluebird-generator.js) 38 | bench+=(${benchpath}/promises-then-promise.js) 39 | bench+=(${benchpath}/promises-native-async-await.js) 40 | 41 | for node in ${nodelist[@]}; do 42 | ${node} ${root}/performance.js --n 10000 --t 1 --p 25 ${bench[@]} --harmony 43 | done 44 | fi 45 | 46 | -------------------------------------------------------------------------------- /build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -exu -o pipefail 4 | cwd=$(cd $(dirname $0) && pwd) 5 | 6 | mkdir -p node 7 | cd node 8 | 9 | files+=(latest-v6.x/node-v6.16.0-linux-x64.tar.xz) 10 | files+=(latest-v8.x/node-v8.15.0-linux-x64.tar.xz) 11 | files+=(latest-v10.x/node-v10.15.0-linux-x64.tar.xz) 12 | 13 | for file in ${files[@]}; do 14 | curl -sfL https://nodejs.org/dist/${file} -O 15 | tar Jxf $(basename ${file}) 16 | nodelist+=(${cwd}/node/$(basename ${file} | sed s'/\.tar\.xz$//')/bin/node) 17 | done 18 | 19 | test ! -d v8-node && git clone https://github.com/v8/node v8-node 20 | cd v8-node 21 | ./configure --build-v8-with-gn 22 | make -j4 node 23 | nodelist+=(${cwd}/node/v8-node/out/Release/node) 24 | 25 | echo ${nodelist[@]} > ${cwd}/node/nodelist 26 | cd ${cwd} 27 | 28 | mkdir -p deps 29 | cd deps 30 | test ! -d bluebird && git clone https://github.com/petkaantonov/bluebird 31 | cd bluebird 32 | npm install 33 | cp ${cwd}/generators-tj-co.js ./benchmark/madeup-parallel/generators-tj-co.js 34 | 35 | -------------------------------------------------------------------------------- /generators-tj-co.js: -------------------------------------------------------------------------------- 1 | global.useNative = true; 2 | 3 | try { 4 | if (Promise.race.toString() !== 'function race() { [native code] }') 5 | throw 0; 6 | } catch (e) { 7 | throw new Error("No ES6 promises available"); 8 | } 9 | 10 | var co = require('co'); 11 | require('../lib/fakesP'); 12 | 13 | module.exports = function upload(stream, idOrPath, tag, done) { 14 | return co(function* () { 15 | var queries = new Array(global.parallelQueries); 16 | var tx = db.begin(); 17 | 18 | for( var i = 0, len = queries.length; i < len; ++i ) { 19 | queries[i] = FileVersion.insert({index: i}).execWithin(tx); 20 | } 21 | 22 | try { 23 | yield Promise.all(queries); 24 | tx.commit(); 25 | done(); 26 | } 27 | catch(e) { 28 | tx.rollback(); 29 | done(e); 30 | } 31 | }); 32 | }; 33 | --------------------------------------------------------------------------------