HomeSearch

C# BufferedStream: Optimize Read and Write

This C# benchmark article tests the BufferedStream class on a MemoryStream. With BufferedStream the WriteByte method goes faster.
BufferedStream. With a buffer, we avoid executing writes and reads until a certain number of operations has been requested. Then we execute them all at once.File
An optimization. Buffering makes things faster—many bytes can be written at once, reducing overhead of each byte. The BufferedStream in C# can be used to optimize stream reads and writes.
Example program. Consider this program. It uses a MemoryStream and we want to write 5 million bytes to it. But we wrap the MemoryStream in a BufferedStream.

And: We call WriteByte on the BufferedStream, which acts upon the MemoryStream. But it buffers operations.

Result: The total time required for the 5 million buffered WriteByte calls is printed as the program exits.

C# program that benchmarks BufferedStream using System; using System.Diagnostics; using System.IO; class Program { static void Main() { var t1 = Stopwatch.StartNew(); // Use BufferedStream to buffer writes to a MemoryStream. using (MemoryStream memory = new MemoryStream()) using (BufferedStream stream = new BufferedStream(memory)) { // Write a byte 5 million times. for (int i = 0; i < 5000000; i++) { stream.WriteByte(5); } } t1.Stop(); Console.WriteLine("BUFFEREDSTREAM TIME: " + t1.Elapsed.TotalMilliseconds); } } Output BUFFEREDSTREAM TIME: 20.6607
Benchmark, part 2. We must compare our BufferedStream benchmark to another one without BufferedStream. Here we use MemoryStream directly—no buffering is done.

Result: The 5 million WriteByte calls in this program take an entire 5 milliseconds more than in the version that uses BufferedStream.

C# program that benchmarks MemoryStream, no buffer using System; using System.Diagnostics; using System.IO; class Program { static void Main() { var t1 = Stopwatch.StartNew(); // Use MemoryStream directly with no buffering. using (MemoryStream memory = new MemoryStream()) { // Write a byte 5 million times. for (int i = 0; i < 5000000; i++) { memory.WriteByte(5); } } t1.Stop(); Console.WriteLine("MEMORYSTREAM TIME: " + t1.Elapsed.TotalMilliseconds); } } Output MEMORYSTREAM TIME: 26.2119
Notes, performance. By using BufferedStream, we achieved a performance boost. This would not be helpful on small streams or fewer writes.
Notes, continued. To achieve "optimal" performance, we need to always measure. But BufferedStream is a good option to try to improve stream read and write performance.

Tip: Optimal performance is "undecidable" which means no program is optimal because another might someday exist that is faster.

A summary. Most programs will not benefit from BufferedStream. But it is good to know it exists. It can improve both reads and writes.
© 2007-2019 Sam Allen. Every person is special and unique. Send bug reports to info@dotnetperls.com.
Home
Dot Net Perls