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

JavaScript JavaScript
スポンサーリンク

では次のステップとして、Worker を動的に増減させて負荷に応じた自動スケーリング を行うサンプルを作ります。これにより、ブラウザが空いている CPU コアを最大限に活用しつつ、負荷に応じて Worker 数を調整できます。


例:自動スケーリング Worker で巨大多次元配列を効率処理

1️⃣ メイン HTML(UI + 自動スケーリング管理)

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>自動スケーリング Worker デモ</title>
<style>
  #progress {
    width: 100%;
    background-color: #eee;
    border-radius: 5px;
    overflow: hidden;
    margin: 10px 0;
  }
  #bar {
    height: 20px;
    background-color: #4CAF50;
    width: 0%;
  }
  #status { font-family: monospace; }
</style>
</head>
<body>
<h1>自動スケーリング Worker デモ</h1>
<div id="progress"><div id="bar"></div></div>
<p id="status">準備中...</p>

<script>
const maxWorkers = navigator.hardwareConcurrency || 4; // 利用可能コア数
let workers = [];
let taskQueue = [];
let activeWorkers = 0;
let sumTotal = 0;

const rows = 1000, cols = 1000;

// データを小さなタスク単位に分割
for (let i = 0; i < rows; i += 50) {
  taskQueue.push({ startRow: i, endRow: Math.min(i + 50, rows), cols });
}

// Worker 作成関数
function startWorker(task) {
  const worker = new Worker('worker-multi.js');
  activeWorkers++;
  worker.onmessage = function(e) {
    const data = e.data;
    if (data.done) {
      sumTotal += data.sum;
      activeWorkers--;
      if (taskQueue.length > 0) {
        startWorker(taskQueue.shift()); // 次のタスクを割り当て
      } else if (activeWorkers === 0) {
        document.getElementById('status').textContent =
          `完了! 合計 = ${sumTotal}`;
        document.getElementById('bar').style.width = '100%';
      }
    } else if (data.progress !== undefined) {
      const percent = Math.min(100,
        Math.floor((sumTotal + data.sum) / (rows * cols * 1.0) * 100));
      document.getElementById('bar').style.width = percent + '%';
      document.getElementById('status').textContent =
        `処理中... ${percent}% 合計=${sumTotal + data.sum}`;
    }
  };
  worker.postMessage(task);
  workers.push(worker);
}

// 初期 Worker を最大数まで起動
for (let i = 0; i < Math.min(maxWorkers, taskQueue.length); i++) {
  startWorker(taskQueue.shift());
}
</script>
</body>
</html>
HTML

2️⃣ Worker ファイルは前回の worker-multi.js と同じでOK

  • チャンク処理+条件付き削除+変換+集計
  • postMessage で進捗や完了を通知
  • 複数タスクを順番に割り当てるだけで自動スケーリング対応

ポイント解説

  1. タスク単位で負荷分散
    • データを小さなタスク(例:50行ごと)に分割
    • Worker 数を最大限活用しつつ、負荷に応じてタスクを割り当てる
  2. 動的スケーリング
    • タスク完了後に次のタスクを Worker に割り当てる
    • 空いている CPU コアを自動的に利用
  3. 進捗バー表示
    • 各 Worker から進捗を受け取り、合計でバーを更新
    • 巨大データでも UI は滑らか
  4. 安全かつ高速
    • 中間配列を最小化、チャンク処理、Worker 分散
    • ブラウザフリーズなし、効率的な並列処理

💡 応用例

  • ブラウザでの巨大 CSV/スプレッドシートのリアルタイム解析
  • ゲームや物理シミュレーションでの CPU 分散処理
  • 大規模統計・画像処理・データ加工アプリ
タイトルとURLをコピーしました