Skip to content

Instantly share code, notes, and snippets.

@dbremner
Last active March 11, 2019 16:54
Show Gist options
  • Save dbremner/b6108bf54ba5eca045d20e64a6dd62a3 to your computer and use it in GitHub Desktop.
Save dbremner/b6108bf54ba5eca045d20e64a6dd62a3 to your computer and use it in GitHub Desktop.
BufferedStream vs NetworkStream benchmark
// Steven Toub wrote this in https://github.com/dotnet/corefx/issues/1793#issuecomment-151584410
// I have made only minor changes.
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
class Program
{
const int NumWrites = 100000;
static void Main()
{
while (true)
{
RunWithConnectedNetworkStreamsAsync(async (server, client) =>
{
var sw = Stopwatch.StartNew();
using (var bufferedServer = new BufferedStream(server))
using (var bufferedClient = new BufferedStream(client))
{
await TransferAsync(bufferedServer, bufferedClient);
}
Console.WriteLine("Buffered: " + sw.Elapsed.TotalSeconds);
}).Wait();
RunWithConnectedNetworkStreamsAsync(async (server, client) =>
{
var sw = Stopwatch.StartNew();
await TransferAsync(server, client);
Console.WriteLine("Unbuffered: " + sw.Elapsed.TotalSeconds);
}).Wait();
Console.WriteLine();
}
}
static Task TransferAsync(Stream server, Stream client)
{
return Task.WhenAll(
Task.Run(() =>
{
for (int i = 0; i < NumWrites; i++)
{
server.WriteByte((byte)i);
}
server.Flush();
}),
Task.Run(() =>
{
for (int i = 0; i < NumWrites; i++)
{
client.ReadByte();
}
}));
}
private static async Task RunWithConnectedNetworkStreamsAsync(Func<NetworkStream, NetworkStream, Task> func)
{
var listener = new TcpListener(IPAddress.Loopback, 0);
try
{
listener.Start(1);
var clientEndpoint = (IPEndPoint)listener.LocalEndpoint;
using (var client = new TcpClient(clientEndpoint.AddressFamily))
{
Task<TcpClient> remoteTask = listener.AcceptTcpClientAsync();
Task clientConnectTask = client.ConnectAsync(clientEndpoint.Address, clientEndpoint.Port);
await Task.WhenAll(remoteTask, clientConnectTask);
using (TcpClient remote = remoteTask.Result)
using (NetworkStream serverStream = remote.GetStream())
using (NetworkStream clientStream = client.GetStream())
{
await func(serverStream, clientStream);
}
}
}
finally
{
listener.Stop();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment