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

JavaScript JavaScript
スポンサーリンク

では、最後のステップとして、多次元配列+複数キュー操作+条件付き削除+集計+UI更新を最適化したプロ仕様サンプル を作ります。


例:多次元配列を複数キューで安全かつ高速に操作(進捗+集計+UI更新付き)

<!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: #FF9800;
    width: 0%;
  }
  #log {
    max-height: 200px;
    overflow-y: auto;
    border: 1px solid #ccc;
    padding: 5px;
    font-family: monospace;
  }
</style>
</head>
<body>
<h1>プロ仕様 多次元配列処理デモ</h1>
<div id="progress"><div id="bar"></div></div>
<p id="status">準備中...</p>
<div id="log"></div>

<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() { if (this.head > 10000) { this.data = this.data.slice(this.head); this.head = 0; } }
}

// 2つのキューで多次元配列を分割して管理
const rows = 1000, cols = 1000;
let queueA = new FastQueue();
let queueB = new FastQueue();
for (let i = 0; i < rows; i++) {
  let row = Array.from({length: cols}, (_, j) => j);
  (i % 2 === 0 ? queueA : queueB).enqueue(row);
}

const chunk = 10; // 1回に処理する行数
let processed = 0;
let sum = 0;
const logEl = document.getElementById('log');

function processChunk() {
  let queues = [queueA, queueB];

  for (let q of queues) {
    let chunkCount = 0;
    while (chunkCount < chunk && q.size() > 0) {
      let row = q.dequeue();

      // 条件付き削除&変換
      let newRow = [];
      for (let val of row) {
        if (val % 2 === 0) {
          val = val * 2;
          sum += val;
          newRow.push(val);
        }
      }
      if (newRow.length > 0) q.enqueue(newRow);
      chunkCount++;
    }
    q.compact();
  }

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

  // ログ更新(最後の5行だけ表示)
  logEl.textContent = `合計 = ${sum}, queueAサイズ=${queueA.size()}, queueBサイズ=${queueB.size()}`;

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

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

ポイント解説

  1. 複数キューで負荷分散
    • queueA / queueB に行を分けて処理
    • 並列処理ではないが、構造的に複雑なデータも安全に扱える
  2. 条件付き削除+変換+集計を一括処理
    • 各行に対して filter/map 相当の操作を一度のループでまとめる
    • 中間配列は行単位のみ → メモリ効率良好
  3. チャンク処理でブラウザフリーズ防止
    • setTimeout で少しずつ処理し、UI 更新も可能
  4. 進捗バー+ログ表示
    • 実行状況を視覚的に確認
    • queue サイズや合計をリアルタイムで表示
  5. メモリ圧縮
    • compact() で head が大きくなったキューを圧縮
    • 巨大データでも安定して処理可能

💡 このサンプルの応用

  • 巨大スプレッドシートや2Dマップデータのリアルタイム更新
  • 条件付きで大量データを加工・集計する Web アプリ
  • 大規模ゲームのエンティティ更新やシミュレーション処理
タイトルとURLをコピーしました