0Pricing
C# Academy · 课时

吞吐量与延迟的权衡

平衡每秒完成的总工作量(吞吐量)与每个项目所需的时间(延迟):比较逐项处理、批处理和并行度调节。

吞吐量与延迟的权衡 是 CoddyKit 上的免费 C# Academy 课时。 这是第 3 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C# Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C# Academy 课程共包含 3 节课。

吞吐量与延迟

定义:

  • 吞吐量:每秒处理的项目数
  • 延迟:完成一个项目所需的时间
  • 权衡:批处理和更高的并行度可能提高吞吐量,但会延迟单个项目的处理

逐项处理模式

项目到达后立即逐个处理:每个项目的等待时间最短,但每个项目都会重复产生开销。

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);
  }
}

调优提示

调优指南:

  • 同时测量每项毫秒数和每秒项目数
  • 先尝试微批次
  • 逐步提高并行度;观察 CPU 和上下文切换
  • 使用有界队列,避免长时间等待和内存增长

吞吐量与延迟的权衡

快速检查:哪项更改通常可以提高吞吐量,但可能增加单个项目的延迟?

回顾

回顾:逐项处理 = 低延迟、较低吞吐量。大批次/高 DOP = 更高吞吐量、更高延迟。微批次和谨慎调节 DOP 有助于平衡两者。

常见问题解答

「吞吐量与延迟的权衡」课时是免费的吗?

是的 — 「吞吐量与延迟的权衡」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 3 节课。

「吞吐量与延迟的权衡」这节课中我会学到什么?

平衡每秒完成的总工作量(吞吐量)与每个项目所需的时间(延迟):比较逐项处理、批处理和并行度调节。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 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