概要
Promiseの(bluebridの)配列系ループの時間計測メモ
promise_looptest.js
const Promise = require('bluebird');
const array = [];
for(let i = 0; i < 10000000; ++i){
array.push(i);
}
console.time('map');
let count = 0;
return Promise.map(array, (a) => {
++count;
return a;
})
.then(() => {
console.timeEnd('map');
console.log(count);
count = 0;
console.time('each');
return Promise.each(array, (a) => {
++count;
return a;
});
})
.then(() => {
console.timeEnd('each');
console.log(count);
count = 0;
console.time('reduce');
return Promise.reduce(array, (promise, a) => {
++count;
return a;
}, 0);
})
.then(() => {
console.timeEnd('reduce');
console.log(count);
count = 0;
console.time('all');
return Promise.all(array.map((a) => {
++count;
return a;
}))
})
.then(() => {
console.timeEnd('all');
console.log(count);
})
結果
map: 1300.333ms
10000000
each: 1641.458ms
10000000
reduce: 1466.863ms
10000000
all: 5150.526ms
10000000
mapが微妙に早い。
誤差のようなきもするけど、何回かしてみてもmapが
一番早い。
別の角度から
promise_looptest2.js
const Promise = require('bluebird');
const array = [];
for(let i = 0; i < 10000000; ++i){
array.push(i);
}
console.time('map');
let count = 0;
return Promise.map(array, (a) => {
return Promise.resolve()
.then(() => {
++count;
return a;
});
})
.then(() => {
console.timeEnd('map');
console.log(count);
count = 0;
console.time('each');
return Promise.each(array, (a) => {
return Promise.resolve()
.then(() => {
++count;
return a;
});
});
})
.then(() => {
console.timeEnd('each');
console.log(count);
count = 0;
console.time('reduce');
return Promise.reduce(array, (promise, a) => {
return Promise.resolve()
.then(() => {
++count;
return a;
});
}, 0);
})
.then(() => {
console.timeEnd('reduce');
console.log(count);
count = 0;
console.time('all');
return Promise.all(array.map((a) => {
return Promise.resolve()
.then(() => {
++count;
return a;
});
}))
})
.then(() => {
console.timeEnd('all');
console.log(count);
})
とPromiseを返すようにしてみる。
結果
mapでout of memory
<--- Last few GCs --->
14801 ms: Mark-sweep 1401.0 (1440.9) -> 1401.0 (1440.9) MB, 1042.0 / 0.0 ms (+ 0.7 ms in 2 steps since start of marking, biggest step 0.6 ms) [allocation failure] [scavenge might not succeed].
16553 ms: Mark-sweep 1401.0 (1440.9) -> 1401.0 (1440.9) MB, 1751.2 / 0.0 ms [allocation failure] [scavenge might not succeed].
<--- JS stacktrace --->
Cannot get stack trace in GC.
FATAL ERROR: MarkCompactCollector: semi-space copy, fallback in old gen Allocation failed - JavaScript heap out of memory
現時点での結果
何がダメでout of memoryかの原因は調査予定。
挙動を見ていた感じだと
全部のPromiseを展開するまでmapはまっているように見えた。
なぜ待つのかを調査してみたい。