0Pricing
C# Academy · レッスン

スループットとレイテンシーのトレードオフ

1秒あたりの総処理量(スループット)と1項目あたりの処理時間(レイテンシー)のバランスを取ります。項目単位の処理、バッチ処理、並列度の調整を比較します。

「スループットとレイテンシーのトレードオフ」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン3/3です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全3レッスンが含まれています。

スループットとレイテンシ

定義:

  • スループット:1秒あたりの処理アイテム数
  • レイテンシ:1つのアイテムの処理を完了するまでの時間
  • トレードオフ:バッチ処理や並列度の向上によってスループットは上がる可能性がありますが、個々のアイテムの処理が遅れる場合があります

アイテム単位の方式

到着した各アイテムをすぐに処理します。アイテムごとの待ち時間は最小になりますが、オーバーヘッドがアイテムごとに繰り返し発生します。

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
  // Simulate small per-item cost
  static void HandleItem(int x)
  {
    // Fixed overhead per item
    Thread.SpinWait(20000); // tiny CPU work
  }

  public static void Main(string[] args)
  {
    int n = 200;
    Stopwatch sw = Stopwatch.StartNew();
    for (int i = 0; i < n; i++)
    {
      HandleItem(i);         // process immediately (no batching)
      // emit result right away (low latency style)
    }
    sw.Stop();
    Console.WriteLine("Per-item style: {0} ms for {1} items", sw.ElapsedMilliseconds, n);
  }
}

バッチ処理方式

バッチ処理によって繰り返し発生するオーバーヘッドを削減し、スループットを向上させられますが、先に到着したアイテムはバッチが満たされるまで待つため、レイテンシが高くなります。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;

public class Program
{
  static void ProcessBatch(List<int> batch)
  {
    // Amortize overhead across the whole batch
    Thread.SpinWait(20000);        // one-time overhead
    for (int i = 0; i < batch.Count; i++)
    {
      // small per-record work
      int val = batch[i] * 2;
      if (val == int.MinValue) { } // keep compiler from dropping work
    }
  }

  public static void Main(string[] args)
  {
    int n = 200;
    int batchSize = 20;
    List<int> current = new List<int>(batchSize);

    Stopwatch sw = Stopwatch.StartNew();
    for (int i = 0; i < n; i++)
    {
      current.Add(i);
      if (current.Count == batchSize)
      {
        ProcessBatch(current);
        current.Clear(); // emit results after the batch finishes
      }
    }
    if (current.Count > 0) ProcessBatch(current);
    sw.Stop();

    Console.WriteLine("Batch style: {0} ms for {1} items (batch={2})", sw.ElapsedMilliseconds, n, batchSize);
  }
}

並列度の調整

MaxDegreeOfParallelismを調整すると、CPUバウンドの処理でスループットを向上させられます。ただし、高くしすぎるとコンテキストスイッチによって性能が低下する場合があります。

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
  static void Work(int x)
  {
    // CPU-bound unit
    Thread.SpinWait(40000);
  }

  public static void Main(string[] args)
  {
    int[] data = new int[200];
    for (int i = 0; i < data.Length; i++) data[i] = i;

    foreach (int dop in new int[] { 1, 2, 4 })
    {
      var opt = new ParallelOptions();
      opt.MaxDegreeOfParallelism = dop;

      Stopwatch sw = Stopwatch.StartNew();
      Parallel.ForEach(data, opt, Work);
      sw.Stop();

      Console.WriteLine("DOP={0} -> {1} ms", dop, sw.ElapsedMilliseconds);
    }
  }
}

マイクロバッチの考え方

マイクロバッチを使用すると、両方の目標のバランスを取れます。アイテム単位の処理よりスループットが高く、大きなバッチよりレイテンシを低くできます。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
  static void ProcessBatch(List<int> batch)
  {
    Thread.SpinWait(15000); // small shared overhead
    for (int i = 0; i < batch.Count; i++) Thread.SpinWait(2000);
  }

  public static void Main(string[] args)
  {
    int n = 200;
    int micro = 5; // micro-batch size
    List<int> buf = new List<int>(micro);
    Stopwatch sw = Stopwatch.StartNew();

    for (int i = 0; i < n; i++)
    {
      buf.Add(i);
      if (buf.Count == micro)
      {
        ProcessBatch(buf);
        buf.Clear(); // emit more frequently than big batches
      }
    }
    if (buf.Count > 0) ProcessBatch(buf);

    sw.Stop();
    Console.WriteLine("Micro-batch (size={0}): {1} ms", micro, sw.ElapsedMilliseconds);
  }
}

調整のヒント

調整ガイド:

  • ms/itemとitems/secの両方を計測します
  • まずはマイクロバッチを試します
  • 並列度を徐々に上げ、CPU使用率とコンテキストスイッチを監視します
  • 長い待ち時間やメモリの増加を避けるため、キューに上限を設けます

スループットとレイテンシのトレードオフ

簡単な確認です。通常、スループットを向上させる一方で、アイテムごとのレイテンシを増加させる可能性がある変更はどれですか?

まとめ

まとめ:アイテム単位の処理はレイテンシが低く、スループットも低くなります。大きなバッチや高いDOPはスループットが高く、レイテンシも高くなります。マイクロバッチとDOPの慎重な調整によって、両方のバランスを取れます。

よくある質問

「スループットとレイテンシーのトレードオフ」レッスンは無料ですか?

はい。「スループットとレイテンシーのトレードオフ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全3レッスンが含まれています。

「スループットとレイテンシーのトレードオフ」で何を学びますか?

1秒あたりの総処理量(スループット)と1項目あたりの処理時間(レイテンシー)のバランスを取ります。項目単位の処理、バッチ処理、並列度の調整を比較します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C# Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/3です。

「スループットとレイテンシーのトレードオフ」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC# Academyレッスンでコードを書いて実行できますか?

はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Parallel.ForEach、PLINQ
  2. Channelsによるプロデューサー/コンシューマー(概要)
  3. スループットとレイテンシーのトレードオフ
← C# Academyに戻る