Is Stream.Copy piped?

c#, stream, tcp

Solution

Here's the implementation of `CopyTo` in .NET 4.5:

private void InternalCopyTo(Stream destination, int bufferSize)
{
    int num;
    byte[] buffer = new byte[bufferSize];
    while ((num = this.Read(buffer, 0, buffer.Length)) != 0)
    {
        destination.Write(buffer, 0, num);
    }
}

So as you can see, it reads from the source, then writes to the destination. This could probably be improved ;)

EDIT: here's a possible implementation of a piped version:

public static void CopyToPiped(this Stream source, Stream destination, int bufferSize = 0x14000)
{
    byte[] readBuffer = new byte[bufferSize];
    byte[] writeBuffer = new byte[bufferSize];

    int bytesRead = source.Read(readBuffer, 0, bufferSize);
    while (bytesRead > 0)
    {
        Swap(ref readBuffer, ref writeBuffer);
        var iar = destination.BeginWrite(writeBuffer, 0, bytesRead, null, null);
        bytesRead = source.Read(readBuffer, 0, bufferSize);
        destination.EndWrite(iar);
    }
}

static void Swap<T>(ref T x, ref T y)
{
    T tmp = x;
    x = y;
    y = tmp;
}

Basically, it reads a chunk synchronously, starts to copy it to the destination asynchronously, then read the next chunk and waits for the write to complete.

I ran a few performance tests:

- using `MemoryStream`s, I didn't expect a significant improvement, since it doesn't use IO completion ports (AFAIK); and indeed, the performance is almost identical

- using files on different drives, I expected the piped version to perform better, but it doesn't... it's actually slightly slower (by 5 to 10%)

So it apparently doesn't bring any benefit, which is probably the reason why it isn't implemented this way...

Problem

Suppose I am writing a tcp proxy code. I am reading from the incoming stream and writing to the output stream. I know that Stream.Copy uses a buffer, but my question is: Does the Stream.Copy method writes to the output stream while fetching the next chunk from the input stream or it a loop like "read chunk from input, write chunk to ouput, read chunk from input, etc" ?

Original source

Related problems