0Pricing
C# Academy · Lezione

Compromessi tra throughput e latenza

Bilanciate il lavoro totale al secondo (throughput) con il tempo per elemento (latenza): confrontate l’elaborazione per elemento, il batching e la regolazione del grado di parallelismo.

Compromessi tra throughput e latenza è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 3 di 3. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 3 lezioni in totale.

Throughput e latenza

Definizioni:

  • Throughput: elementi al secondo
  • Latenza: tempo necessario per completare un elemento
  • Compromesso: l'elaborazione in batch e un parallelismo maggiore possono aumentare il throughput, ma ritardare i singoli elementi

Stile per elemento

Elabori ogni elemento appena arriva: attesa minima per elemento, ma il sovraccarico si ripete per ogni elemento.

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

Stile batch

L'elaborazione in batch riduce il sovraccarico ripetuto e aumenta il throughput, ma i primi elementi attendono il completamento del batch, con una latenza maggiore.

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

Ottimizzazione del parallelismo

L'ottimizzazione di MaxDegreeOfParallelism può aumentare il throughput per il lavoro vincolato dalla CPU; un valore troppo alto può peggiorare le prestazioni a causa dei cambi di contesto.

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

Idea dei micro-batch

I micro-batch possono bilanciare entrambi gli obiettivi: throughput migliore rispetto all'elaborazione per elemento e latenza inferiore rispetto ai batch enormi.

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

Suggerimenti per l'ottimizzazione

Guida all'ottimizzazione:

  • Misuri sia ms/item sia items/sec
  • Provi prima i micro-batch
  • Aumenti gradualmente il parallelismo; controlli la CPU e i cambi di contesto
  • Limiti la capacità delle code per evitare attese prolungate e crescita della memoria

Compromesso tra throughput e latenza

Verifica rapida: quale modifica in genere migliora il throughput, ma può aumentare la latenza per elemento?

Riepilogo

Riepilogo: per elemento = latenza bassa, throughput inferiore. Batch grandi o DOP elevato = throughput maggiore, latenza maggiore. I micro-batch e un'attenta ottimizzazione del DOP aiutano a bilanciare entrambi.

Domande Frequenti

La lezione «Compromessi tra throughput e latenza» è gratuita?

Sì — il testo completo di «Compromessi tra throughput e latenza» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 3 lezioni in totale.

Cosa imparerò in «Compromessi tra throughput e latenza»?

Bilanciate il lavoro totale al secondo (throughput) con il tempo per elemento (latenza): confrontate l’elaborazione per elemento, il batching e la regolazione del grado di parallelismo. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C# Academy?

Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 3.

Quanto tempo richiede la lezione «Compromessi tra throughput e latenza»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C# Academy?

Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Parallel.ForEach, PLINQ
  2. Producer/consumer con Channels (panoramica)
  3. Compromessi tra throughput e latenza
← Torna a C# Academy