WebGL用に自前の関数で4Mb程度のobj読み込みをした
ポリゴン命令の頂点の重複除去をしたあと
index bufferの生成にindexOfを
全ポリゴン命令約21万に対して回していたら43秒掛かった
なんだこれは
indexOf
どちらも検索開始位置を第二引数に指定できる
そこから配列の中を一つづつ検索していく
これは目的の要素を配列の最後に置いて二つを走らせることでわかる
一つだけのインデックスを調べたいのならこれでも十分だが
全要素に対して検索をすると膨大な時間がかかる
並べ替えや重複除去の操作をした後に
全要素の位置を配列に記録する等の用途であれば
先に辞書を作った方が良いことは明らか
#Map
new Map()はObject.fromEntries()のように引数に[[key,value]...]を渡すことでMapを作ることができる
今回はkeyに値を持ってvalueにインデックスを持たせたいがこれは.map()で簡単に作れる
new Map(array.map((x,i)=>[x,i]));
このMapにインデックスが欲しい値を渡すと値が最後に登場するインデックスを取得できる
最初のインデックスが欲しければ
new Map(array.reverse().map((x,i)=>[x,i]));
※追記(2022/1/15)
書いていて多少不安は残るがmapの中の関数はArrayコンストラクタでも動く
Entriesは一番目と二番目の要素のみ保証されていれば良いらしい
つまり
new Map(array.map(Array));
短いね
#速い
重複のある配列Aから重複を除去した配列Bの対応を明確にする目的で
Aと同じ長さのBのインデックスの羅列Cを取得する
Aの長さは208353 Bの長さは34834 である
C=A.map(x=>B.indexOf(x));
const map=new Map(B.map((x,i)=>[x,i]));
C=A.map(x=>map.get(x));
indexOfを使ったコードは43秒ほど掛かったが
Mapを使ったコードでは300ms周辺で済んだ
Mapの代わりにObjectも使ってみたが平均して20msほどObjectの方が遅かった
#indexOfをforするなら先に辞書を作ろう