100万件の文字に任意の文字が含まれるか選手権を開催いたします。
TL;DR
V8に最適化なんて入ってなかった
セットアップ
const array = Array(1000000).fill().map(()=>Math.random().toString().slice(-8))
const object = Object.fromEntries(array.map(a => [a]))
const map = new Map(array.map(a => [a]))
const set = new Set(array)
Array.includes() 251 ops/s
array.includes(Math.random().toString().slice(-8))
Array.indexOf() 229 ops/s
array.indexOf(Math.random().toString().slice(-8))
Object[key] 1,957,463 ops/s
object[Math.random().toString().slice(-8)]
Object.hasOwnProperty() 2,217,807 ops/s
object.hasOwnProperty(Math.random().toString().slice(-8))
key in Object 2,193,181 ops/s
Math.random().toString().slice(-8) in object
Map.has() 1,430,881 ops/s
map.has(Math.random().toString().slice(-8))
Set.has() 1,783,334 ops/s
set.has(Math.random().toString().slice(-8))
for 205 ops/s
const target = Math.random().toString().slice(-8)
let exists = false
const length = array.length
for(var i = 0; i < length; i++) {
if (array[i] === target) {
exists = true
break
}
}
Node.js
key in Object
が最速っぽい?
array.includes(Math.random().toString().slice(-8)) 255.31212026521055
array.indexOf(Math.random().toString().slice(-8)) 273.96164583508994
object[Math.random().toString().slice(-8)] 1377596.804375387
object.hasOwnProperty(Math.random().toString().slice(-8)) 1686838.1590012764
Math.random().toString().slice(-8) in object 1750538.4657379298
map.has(Math.random().toString().slice(-8)) 1347472.81481226
set.has(Math.random().toString().slice(-8)) 1391667.3915078628
const array = Array(1000000).fill().map(() => Math.random().toString().slice(-8))
const object = Object.fromEntries(array.map(a => [a]))
const map = new Map(array.map(a => [a]))
const set = new Set(array)
const functions = [
() => array.includes(Math.random().toString().slice(-8)),
() => array.indexOf(Math.random().toString().slice(-8)),
() => object[Math.random().toString().slice(-8)],
() => object.hasOwnProperty(Math.random().toString().slice(-8)),
() => Math.random().toString().slice(-8) in object,
() => map.has(Math.random().toString().slice(-8)),
() => set.has(Math.random().toString().slice(-8)),
]
for (const func of functions) {
const iters = 10000
const now = performance.now()
Array(iters).fill().forEach(func)
console.log(func.toString().slice(6), iters / (performance.now() - now) * 1000)
}
AWS Lambda
START RequestId: 27e4dd98-6b69-471f-93c6-18b8e7c60a9b Version: $LATEST
2023-02-24T00:19:42.323Z 27e4dd98-6b69-471f-93c6-18b8e7c60a9b INFO array.includes(Math.random().toString().slice(-8)) 100.11041055746443
2023-02-24T00:21:09.727Z 27e4dd98-6b69-471f-93c6-18b8e7c60a9b INFO array.indexOf(Math.random().toString().slice(-8)) 114.41227075738253
2023-02-24T00:21:09.738Z 27e4dd98-6b69-471f-93c6-18b8e7c60a9b INFO object[Math.random().toString().slice(-8)] 956500.0058246729
2023-02-24T00:21:09.748Z 27e4dd98-6b69-471f-93c6-18b8e7c60a9b INFO object.hasOwnProperty(Math.random().toString().slice(-8)) 1057379.8824432148
2023-02-24T00:21:09.757Z 27e4dd98-6b69-471f-93c6-18b8e7c60a9b INFO Math.random().toString().slice(-8) in object 1051999.1613521294
2023-02-24T00:21:09.770Z 27e4dd98-6b69-471f-93c6-18b8e7c60a9b INFO map.has(Math.random().toString().slice(-8)) 840604.0681615262
2023-02-24T00:21:09.781Z 27e4dd98-6b69-471f-93c6-18b8e7c60a9b INFO set.has(Math.random().toString().slice(-8)) 885716.8416465283
END RequestId: 27e4dd98-6b69-471f-93c6-18b8e7c60a9b
REPORT RequestId: 27e4dd98-6b69-471f-93c6-18b8e7c60a9b Duration: 189717.39 ms Billed Duration: 189718 ms Memory Size: 10240 MB Max Memory Used: 517 MB Init Duration: 212.71 ms
まとめ
- 要素数が少ないなら、
Array.includes(key)
- 短く書きたいなら、
key in Object
- notもつけたいなら
!object.hasOwnProperty(key)