JavaScript | 大きな配列を扱うときのパフォーマンス面

JavaScript JavaScript
スポンサーリンク

では、さらに高度なサンプルとして、条件付き削除(filter相当)+複合変換+進捗バー を使った巨大配列処理をブラウザ上で安全に行う例を作ります。


例:条件付き削除+変換+集計+進捗バー

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>巨大配列条件付き処理デモ</title>
<style>
  #progress {
    width: 100%;
    background-color: #eee;
    border-radius: 5px;
    overflow: hidden;
    margin: 10px 0;
  }
  #bar {
    height: 20px;
    background-color: #673AB7;
    width: 0%;
  }
</style>
</head>
<body>
<h1>巨大配列条件付き処理デモ</h1>
<div id="progress"><div id="bar"></div></div>
<p id="status">準備中...</p>

<script>
// 高速キュークラス
class FastQueue {
  constructor() {
    this.data = [];
    this.head = 0;
  }
  enqueue(v) { this.data.push(v); }
  dequeue() {
    if (this.head >= this.data.length) return undefined;
    return this.data[this.head++];
  }
  size() { return this.data.length - this.head; }
  compact() {
    // head が大きくなったら配列を圧縮
    if (this.head > 10000) {
      this.data = this.data.slice(this.head);
      this.head = 0;
    }
  }
}

// 100万件の配列を用意
const size = 1000000;
let q = new FastQueue();
for (let i = 0; i < size; i++) q.enqueue(i);

const chunk = 10000;
let processed = 0;
let sum = 0;

function processChunk() {
  let chunkCount = 0;
  while (chunkCount < chunk && q.size() > 0) {
    let v = q.dequeue();

    // 条件付き削除: 10000未満は削除
    if (v >= 10000) {
      v = v * 2;     // 変換
      sum += v;      // 集計
      q.enqueue(v);  // 末尾追加
    }

    chunkCount++;
  }

  processed += chunk;
  const percent = Math.min(100, Math.floor((processed / size) * 100));
  document.getElementById('bar').style.width = percent + '%';
  document.getElementById('status').textContent = `処理中... ${percent}%`;

  q.compact(); // メモリ圧縮

  if (processed < size) {
    setTimeout(processChunk, 0);
  } else {
    document.getElementById('status').textContent =
      `完了! 集計合計 = ${sum}, キューサイズ = ${q.size()}`;
  }
}

// スタート
processChunk();
</script>
</body>
</html>
HTML

ポイント解説

  1. 条件付き削除(filter相当)
    • v >= 10000 を満たさない場合は enqueue せず、削除相当の処理
    • 大量データでも shift でコピーせずに効率的に削除
  2. 複合処理
    • 条件チェック → 変換 → 集計 → 末尾追加
    • 一度のループでまとめて処理することで中間配列を作らず高速
  3. 進捗バー
    • チャンクごとに更新することで、ブラウザが固まらず UI も更新可能
  4. 配列圧縮
    • compact() で head が大きくなったら不要部分を削除
    • 巨大配列で head が増えると無駄なメモリが残るので圧縮する
  5. ブラウザ安全性
    • setTimeout で少しずつ処理 → フリーズしない
    • 巨大配列でも UI が応答する

💡 応用例

  • 巨大ログの条件付きフィルタ+加工+集計
  • ゲームやシミュレーションで、条件付きで大量オブジェクトを更新
  • データストリームのリアルタイム集計
タイトルとURLをコピーしました