Last active
March 11, 2019 16:54
-
-
Save dbremner/b6108bf54ba5eca045d20e64a6dd62a3 to your computer and use it in GitHub Desktop.
BufferedStream vs NetworkStream benchmark
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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