Course contentsShow
← C#
Lesson 315 of 1,9083. Generics and Collections ArchitectureFree lesson

Measuring Throughput vs Latency

Benchmark generic collection performance under varying load profiles to validate design choices.

In this lesson, you will learn how to distinguish between throughput and latency when evaluating the performance of generic collections under varying load profiles.

When optimizing collections, developers often confuse how fast a single operation completes versus how much work the system handles in total. Latency is the time it takes for a single operation (like List.Add or ConcurrentQueue.Enqueue) to finish. Throughput is the total number of operations your collection can process within a specific timeframe, such as one second.

Why Load Profiles Matter

A collection that performs well with one thread may collapse under high concurrency. For example, a List<T> may offer excellent, low-latency access for a single thread. However, if you attempt to use it across multiple threads without synchronization, it will either corrupt data or require heavy locking, which spikes latency and tanks your throughput. Conversely, a ConcurrentQueue<T> might have higher base latency due to internal synchronization overhead, but it maintains consistent throughput as you increase the number of producer threads.

To validate your design choices, you should measure these metrics under different "load profiles":

// Simple load testing concept
void BenchmarkCollection(ICollection<int> collection, int threadCount)
{
    var sw = Stopwatch.StartNew();
    Parallel.For(0, threadCount, i => {
        // Measure Latency: Time per operation
        // Measure Throughput: Ops/sec
        collection.Add(i); 
    });
    sw.Stop();
    Console.WriteLine($"Throughput: {threadCount / sw.Elapsed.TotalSeconds} ops/sec");
}

Analyzing the Results

If your latency increases linearly as you add more threads, your collection is likely facing contention (waiting on locks). If your throughput plateaus, your collection architecture has reached a scalability bottleneck. When designing your data structures, aim for low latency if you are building an interactive UI or a real-time system, and prioritize throughput if you are building a background data processing pipeline. By testing under varied thread counts, you ensure your chosen collection handles the "stress" of your specific production environment without unexpected performance degradation.

Key Takeaway: Latency measures the speed of one operation, while throughput measures the volume of work completed; always validate your collection choice against the specific concurrency load of your application.