├── .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 | Node.JS |
11 | V8 |
12 | async type |
13 | time(ms) |
14 | memory(MB) |
15 |
16 |
17 |
18 |
19 | v6.16.0 |
20 | 5.1.281.111 |
21 | callback |
22 | 110 |
23 | 24.49 |
24 |
25 |
26 | async/await |
27 | 731 |
28 | 146.29 |
29 |
30 |
31 | v8.15.0 |
32 | 6.2.414.75 |
33 | callback |
34 | 144 |
35 | 28.30 |
36 |
37 |
38 | async/await |
39 | 447 |
40 | 91.31 |
41 |
42 |
43 | v10.15.0 |
44 | 6.8.275.32-node.45 |
45 | callback |
46 | 153 |
47 | 25.84 |
48 |
49 |
50 | async/await |
51 | 333 |
52 | 66.56 |
53 |
54 |
55 | v11.0.0-pre |
56 | 7.3.0-node.5 (candidate) |
57 | callback |
58 | 166 |
59 | 23.62 |
60 |
61 |
62 | async/await |
63 | 274 |
64 | 56.10 |
65 |
66 |
67 |
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 |
--------------------------------------------------------------------------------