const create = (len) => {
return Array.from(Array(len).keys())
}
const m = create(10000)
const a = create(10000)
const b = create(10000)
const c = create(10000)
const d = create(10000)
console.time()
const result = m.map(id => {
return {
a: a.filter(x => x === id),
b: b.filter(x => x === id),
c: c.filter(x => x === id),
d: d.filter(x => x === id),
}
})
console.timeEnd()
m を基準に各要素に a, b, c, d を id 検索して一致するものを配列で保持する
これだと create ですべて [0, 1, ..., 9999] が入ってるのでフィルターの結果はすべて 1 件
毎回フィルターするのはムダそうに見えるけど
m の 1 要素あたりの処理で 1 万 x 4 = 4 万回の処理
それを m の要素 1 万回なので 4 億回
単に for ループで 4 億回ループしてカウントアップしても 800 ms くらいで 1 秒かからない
また実際には create で作られる a, b, c, d の要素には m の中には含まれない id が多数あって 0 件も多め
事前に a などを id ごとにグループ化できるけど 実際には filter のあとに変換処理の map もあって 使わない要素まで変換するのはムダになりそうという判断で m の map の中で都度フィルター
変換の方がフィルターよりも重たそうと思ってたけど実際は変換は大したことなくて フィルターでかなり遅くなってた
上のコードの実行時間は 21 秒くらい
単純な 4 億回ループの 800ms と比べるとかなり遅い
フィルターを使わずグループ化してみる
上のコードに合わせて フィルターした要素の変換はなし
const create = (len) => {
return Array.from(Array(len).keys())
}
const m = create(10000)
const a = create(10000)
const b = create(10000)
const c = create(10000)
const d = create(10000)
console.time()
const a_map = new Map()
for (const x of a) {
const arr = a_map.get(x)
if (arr) {
arr.push(x)
} else {
a_map.set(x, [x])
}
}
const b_map = new Map()
for (const x of b) {
const arr = b_map.get(x)
if (arr) {
arr.push(x)
} else {
b_map.set(x, [x])
}
}
const c_map = new Map()
for (const x of c) {
const arr = c_map.get(x)
if (arr) {
arr.push(x)
} else {
c_map.set(x, [x])
}
}
const d_map = new Map()
for (const x of d) {
const arr = d_map.get(x)
if (arr) {
arr.push(x)
} else {
d_map.set(x, [x])
}
}
const result = m.map(id => {
return {
a: a_map.get(id),
b: b_map.get(id),
c: c_map.get(id),
d: d_map.get(id),
}
})
console.timeEnd()
結果は 20ms くらいで 1000 倍くらいの高速化
単純な === が条件のフィルターってほぼ無視できるくらいに考えてたけど結構遅めだった
最近は自分でやらなくても groupBy があるので そっちにしてみるともっと短くかける
const create = (len) => {
return Array.from(Array(len).keys())
}
const m = create(10000)
const a = create(10000)
const b = create(10000)
const c = create(10000)
const d = create(10000)
console.time()
const a_group = Object.groupBy(a, x => x)
const b_group = Object.groupBy(b, x => x)
const c_group = Object.groupBy(c, x => x)
const d_group = Object.groupBy(d, x => x)
const result = m.map(id => {
return {
a: a_group[id],
b: b_group[id],
c: c_group[id],
d: d_group[id],
}
})
console.timeEnd()
プロパティの参照のみならオブジェクトが優れると聞いたのでオブジェクトにしてみたけど 速度はほぼ違いなかった