Last time, we concluded that a simple producer/consumer pattern using BlockingCollection topped out at around 2200K items per second. But the profiler revealed that the Throttle itself was one major contributor to the total CPU time. Let’s first address this…
More performance experiments: queues and threads
Continuing from our previous performance experiment, I would like to see if there are any easy optimizations to apply to squeeze more throughput out of this producer/consumer queue. One possible angle of attack is to replace the implicit synchronization primitives…
Performance experiments: queues and threads
The producer-consumer problem is one of the greatest hits of computer science. The classic solution involves some sort of queue data structure and an event or two to notify the consumer(s). Let’s take a look at a simple implementation and…
Efficient concurrency prevention
Sometimes you want asynchrony but not concurrency. For example, if you are writing data to a file, you should generally prefer asynchronous I/O, but you probably don’t want 10 other competing callers to corrupt the contents. Perhaps the simplest way…
Oversubscribe now!
For small chunks of compute-bound work that must be offloaded to the background, you can choose from several APIs and patterns in .NET. In code written before .NET 4.0, you would probably use ThreadPool.QueueUserWorkItem. In modern day apps, you might…
The battle of async methods
In a contest between async proper, Task.Run, and dedicated threads, who will win? Let’s gather some data points for a specific scenario and find out! Today’s benchmark will make use of a trivial single process WCF named pipes application using…
SSD and … sync I/O?
Walter Bright (via Andrei Alexandrescu) says, “Measuring gives you a leg up on experts who are too good to measure.” Today I’ll present some measurements that might be a bit surprising. In the old days of mechanical spinning disks, the…
Orchestrating race conditions
Many a programmer has struggled with unit tests and those pesky race conditions that are seemingly immune to them. Is it even possible to verify concurrency correctness using TDD? I am going to tell you that it is — sometimes.…
Laziness is a virtue
Sometimes you want lazy initialization but your initialization function is asynchronous. Stephen Toub wrote about this conundrum years ago on the pfxteam blog. The solution as he describes it is fairly straightforward — use Lazy<T> combined with Task<T> and you’re…
Native InputQueue thread-safety
In the previous post, I introduced my port of InputQueue to C++. As usual, the unit tests drove the creation of a correct single-threaded implementation but slightly more needed to be done to make the code thread-safe. The go-to construct…