0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【JavaScript】配列・型付き配列・Map・Object 整数添字のアクセスで何が一番速いか対決

0
Posted at

JavaScript には、整数を添え字として指定し、それと関連付けた値を読み書きできる機能がいくつもある。
具体的には、配列型付き配列MapObjectなどがある。
しかし、この中でどれがどのくらい速いのだろうか?
というわけで、実験を行ってみた。

今回の実験

JSBench.me - JavaScript performance benchmarking playground
を用いて、それぞれのデータ構造に適当にアクセスするプログラムを実行し、処理速度を比較する。

具体的には、以下のプログラムを用意した。
型付き配列の実験は、代表として Int32Array で行った。

Array vs Int32Array vs Map (version 1) - JavaScript benchmark at JSBench.me

初期設定 (共通)
const nelem = 10000; 
const niter = 100000;
配列
const array = [];
for (let i = 0; i < nelem; i++) array[i] = i;
for (let i = 0; i < niter; i++) {
  const a = (i * 591364) % nelem;
  const b = (i * 195872) % nelem;
  const t = array[a];
  array[a] = array[b];
  array[b] = t;
}
型付き配列
const array = new Int32Array(nelem);
for (let i = 0; i < nelem; i++) array[i] = i;
for (let i = 0; i < niter; i++) {
  const a = (i * 591364) % nelem;
  const b = (i * 195872) % nelem;
  const t = array[a];
  array[a] = array[b];
  array[b] = t;
}
Map
const array = new Map();
for (let i = 0; i < nelem; i++) array.set(i, i);
for (let i = 0; i < niter; i++) {
  const a = (i * 591364) % nelem;
  const b = (i * 195872) % nelem;
  const t = array.get(a);
  array.set(a, array.get(b));
  array.set(b, t);
}
Object
const array = {};
for (let i = 0; i < nelem; i++) array[i] = i;
for (let i = 0; i < niter; i++) {
  const a = (i * 591364) % nelem;
  const b = (i * 195872) % nelem;
  const t = array[a];
  array[a] = array[b];
  array[b] = t;
}

初期設定で、扱う要素数 nelem および入れ替え処理の回数 niter を定義する。
そして、各データ構造について、以下の処理を行う。

  1. 連番を格納する
  2. 適当な要素を選び、それらの値を入れ替える

適当な要素を選ぶのに Math.random() を用いてしまうと、この中身によって性能に影響が出る懸念があるため、今回は適当な値を掛けて要素数で割った余りを取ることで、適当な要素を選ぶことにした。

今回の処理は、「データ構造に適当な回数アクセスする」ことを目的としており、要素のシャッフルを目的としたものではない。

実験結果

手元の Windows 11 環境で、Firefox 154.0 および Google Chrome 151.0.7922.174 でそれぞれ 1 回測定を行ったところ、以下の結果が得られた。

データ構造 Firefox Google Chrome
配列 830 ops/s ± 0.94% 190 ops/s ± 2.22%
型付き配列 913 ops/s ± 0.6% 189 ops/s ± 5.36%
Map 177 ops/s ± 0.52% 88 ops/s ± 0.84%
Object 815 ops/s ± 1.46% 188 ops/s ± 9.81%

データ構造ごとの処理速度のグラフ

Firefox では、型付き配列のパフォーマンスが若干良く、配列と Object のパフォーマンスが同じくらいで、Map のパフォーマンスが圧倒的に悪かった。
Google Chrome では、Map のパフォーマンスが Firefox ほどの差ではないが悪く、他のパフォーマンスは同じくらいだった。
また、Google Chrome の Map 以外のパフォーマンスは、Firefox の Map 程度しか出なかった。

おわりに

Map は近代的な連想配列でパフォーマンスに優れていると思い込んでいたので、試してみると Object よりもパフォーマンスが出ないというのは意外だった。

また、型付き配列は今回扱った他のデータ構造と比べて要素数の拡大がしにくい。
その分配列よりもパフォーマンスが良くなると思い込んでみたが、試してみるとあまり変わらないこともあるようである。

とはいえ、これはあくまで今回の実験の結果である。
データやクエリの数を変えてみたり、行う処理の内容を変えてみたり (たとえば、不連続な添字や要素の削除を扱う) すると、結果は変わってくるかもしれない。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?