JavaScriptで[0, 1, 2, 3]のような連番の配列を生成する方法と、速度比較を解説します。【JavaScript】performance.now()で処理にかかる時間を計測する方法で紹介した時間測定の関数を使い、7通りの方法での速度を比較検証した結果の共有になります。
連番の配列を生成する方法 7選

上の画像は、0から9までの整数を要素として持つ要素数10の配列を7通りの方法で生成し、コンソールに出力した結果です。各関数に間違いがないか検証前の整合性の確認となります。
以下の時間測定関数を使い、tB1からtB7までの7個の関数を比較しました。
const ITERATION = 100;
const N = 100000;
showPerformanceTime(tB1, ITERATION);
showPerformanceTime(tB2, ITERATION);
showPerformanceTime(tB3, ITERATION);
showPerformanceTime(tB4, ITERATION);
showPerformanceTime(tB5, ITERATION);
showPerformanceTime(tB6, ITERATION);
showPerformanceTime(tB7, ITERATION);
function showPerformanceTime(fn, n = 1) {
const t0 = performance.now();
for (let i = 0; i < n; i++) {
fn();
}
console.log((performance.now() - t0) / n);
}
各関数は、0から99,999までの整数を要素として持つ、要素数100,000個の配列を返す関数となります。このテストでは、各関数を100回施行した実行時間の平均をコンソールに出力します。結果は以下です。

アルゴリズムは大きく2通りの方法で実現しています。赤枠の3つはmap()を使う方法で、青枠の4つはfor文またはwhile文を使う方法となります。結論、赤枠はどれも青枠のものよりも遅いです。青枠の上2つはfor文、下2つはwhile文で、それぞれの上と下で同じアルゴリズムが使われています。結果から分かるように、for文、while文による速度の差はほぼありませんでした(テストを施行するたびにすべての結果は多少変動します)。
これらを踏まえ、関数を上から順に紹介します。
function tB1() {
return Array(N).fill().map((_, i) => i);
}
tB1()関数は、map()を使うものの中では1番速かったです。map()の処理はすべて同じなので、その前のundefinedで満たされた100,000個の要素を持つ配列を作る部分の処理で差がでます。疎配列のままだとmap()が機能しないため、何かで満たされた密配列に変換する必要があります。Array().fill()による疎配列から密配列への変換は、他2つと比べて高速に動作するようです。
function tB2() {
return [...Array(N)].map((_, i) => i);
}
tB2()関数は、すべての処理の中で最も遅かったです。空の配列の中に疎配列を展開することでundefinedで満たされた密配列に変換します。
function tB3() {
return Array.from(Array(N)).map((_, i) => i);
}
tB3()関数は、すべての処理の中で2番目に遅かったです。Array.from()を使い、疎配列をundefinedで満たされた密配列に変換します。
function tB4() {
const arr = [];
for (let i = 0; i < N; i++) {
arr.push(i);
}
return arr;
}
tB4()関数は、tB6()と同じく2番目に速かったです。arrを空配列で初期化し、forループを回しつつ要素をpush()します。
function tB5() {
const arr = Array(N);
for (let i = 0; i < N; i++) {
arr[i] = i;
}
return arr;
}
tB5()関数は、tB7()と同じく最も速かったです。arrを100,000個の疎配列で初期化することで、あらかじめ配列の領域を確保します。その後、forループを回しつつarr[0]から順に値を代入します。
function tB6() {
const arr = [];
let i = 0;
while (i < N) {
arr.push(i);
i++;
}
return arr;
}
tB6()関数は、tB4()と同じく2番目に速かったです。tB4()のfor文をwhile文に置き換えた形となります。
function tB7() {
const arr = Array(N);
let i = 0;
while (i < N) {
arr[i] = i;
i++;
}
return arr;
}
tB7()関数は、tB5()と同じく最も速かったです。tB5()のfor文をwhile文に置き換えた形となります。
結論
連番の配列を生成する方法を7通り比較検証しましたが、結論、for文とwhile文による処理速度の違いはなかったため、5通りの方法として見たときに、各関数の処理速度には割と綺麗に差があることがわかりました(100,000個の配列を生成する場合)。Array()コンストラクターによりあらかじめ配列の領域を確保のち、for文もしくはwhile文によるループで各要素に値を割り当てる方法がより高速だという結果となりました。ただし、while文では変数iを定義する必要があることと、そのインクリメント処理を書く必要があるため2行分コードが長くなり、可読性が損なわれてしまいます。好みによりますが、カウンター変数であるiの処理を1行にまとめて書けるfor文の使用をおすすめします(tB5()関数がおすすめ)。
余談ですが、関数名にtB1からtB7を使用した理由は、undefinedで満たされた配列を生成する関数の処理速度の比較に、tA1からtA7の関数名を使用したためです。tはテストの略で、AもしくはBはテストtype(もしくはパターン)。