为什么c#内置IO类比自制类快?

10 c# io performance stream

当我决定ByteBuffer在C#中自己实现Java时,我认为它会比MemoryStream+ BinaryWriter/ 更快BinaryReader.我通过ILSpy查看了它们的源代码,并且有很多检查和辅助方法调用,而在我的实现中,我直接使用底层的字节数组.但是当测试显示重内置类的方法调用几乎比我的轻量级方法的调用快两倍时,我感到非常惊讶.

例如:

public void WriteBytes(Byte[] buffer, Int32 offset, Int32 count)
{
    this.EnsureFreeSpace(count);

    Buffer.BlockCopy(buffer, offset, this.buffer, this.position, count);

    this.position += count;
    if (this.length < this.position)
    {
        this.length = this.position;
    }
}

public void ReadBytes(Byte[] buffer, Int32 offset, Int32 count)
{
    this.EnsureDataExist(count);

    Buffer.BlockCopy(this.buffer, this.position, buffer, offset, count);

    this.position += count;
}

private void EnsureFreeSpace(Int32 count)
{
    if (this.buffer.Length - this.position < count)
    {
        throw new InvalidOperationException();
    }
}

private void EnsureDataExist(Int32 count)
{
    if (this.length - this.position < count)
    {
        throw new InvalidOperationException();
    }
}
Run Code Online (Sandbox Code Playgroud)

比慢1.5-2倍

memoryStream.Write(...)
memoryStream.Read(...)
Run Code Online (Sandbox Code Playgroud)

在这个简单的测试中

Byte[] temp = new byte[64];
stopWatch.Restart();
for (int i = 0; i < 100000; i++)
{
    ms.Write(temp, 0, temp.Length);
    ms.Position = 0;
    ms.Read(temp, 0, temp.Length);
    ms.Position = 0;
}
stopWatch.Stop();
Console.WriteLine(stopWatch.ElapsedMilliseconds);

stopWatch.Restart();
for (int i = 0; i < 100000; i++)
{
    mb.WriteBytes(temp, 0, temp.Length);
    mb.Position = 0;
    mb.ReadBytes(temp, 0, temp.Length);
    mb.Position = 0;
}
stopWatch.Stop();
Console.WriteLine(stopWatch.ElapsedMilliseconds);
Run Code Online (Sandbox Code Playgroud)

为什么?

在所有测试优化中都启用了.在调试模式下,平均差异就像我说的那样~1.7倍.在发布模式下~1.3倍,但仍然存在.

编辑 感谢我的建议,我发现在Visual Studio之外,我的代码速度要快几倍,或者至少和内置代码一样快.所以现在的问题是,为什么会发生这种情况?

Die*_*ata 1

我的看法是您未能正确测试其性能。这个主题之前已经讨论过几次,我发现 Eric Lippert 的博客系列非常有启发性:http://tech.pro/blog/1293/c-performance-benchmark-mistakes-part-one

作为快捷方式,请执行以下操作:将整个测试代码放入 for 循环中并运行几次,比较输出并始终丢弃第一个结果。