【问题标题】:Difference between buffer size when streams copying流复制时缓冲区大小之间的差异
【发布时间】:2012-03-09 14:24:39
【问题描述】:

我看到了很多 CopyStream 实现的示例,但我对复制流时的缓冲区大小有疑问。
CopyStreams 实现之一的示例:

private void ReadWriteStream(Stream readStream, Stream writeStream)
{
    int Length = 256;
    Byte[] buffer = new Byte[Length];
    int bytesRead = readStream.Read(buffer, 0, Length);
    // write the required bytes
    while (bytesRead > 0)
    {
        writeStream.Write(buffer, 0, bytesRead);
        bytesRead = readStream.Read(buffer, 0, Length);
    }
    readStream.Close();
    writeStream.Close();
}

问题是:

  • 缓冲区长度应该是多少(我见过 256、8 * 1024、32768)?
  • 不同的缓冲区大小如何影响性能、内存使用等?

相关问题:
File IO with Streams - Best Memory Buffer Size - 不错的文件 IO 答案。但是内存复制呢?


我的情况:
我使用ClosedXML workbook.SaveAs(memoryStream); 创建了MemotyStream,它在托管堆中分配了大量内存。我查看了源代码,发现有使用 8 * 1024 缓冲区大小的 CopyStream 方法。改变这个大小会以某种方式减少内存使用吗?
注意: Stream 占用将近 1Gb 的内存。

【问题讨论】:

  • 在您的情况下,可能是内存流使用了大部分内存而不是复制过程?值得检查,因为 8KB 缓冲区对于数百 MB 的流来说是很小的。
  • 您的 XML 文档的大小是多少(写入磁盘时)?如果它是 1GB,那么您应该期望内存流为 1GB...或者如果不是 - 好 - 到(托管)内存,您希望数据去哪里?
  • @Markus Excel 文件本身只需要 20MB。这绝对是一个坏兆头。
  • "Stream 占用将近 1GB 内存?"这是否意味着,流的大小如此之大,或者您的应用程序在保存后仅使用 1GB 额外内存?您是否在内部调试过 ClosedXML?在(内部)保存方法之前设置一个断点,并确定内存是否恰好在那里增加(或找出有问题的调用)。或者,您可能想要附加分析器。

标签: c# optimization stream buffer


【解决方案1】:

如果您使用的是 .NET 4,则可以更简单:

srcStream.CopyTo(dstStream);

但如果您想/需要自己实现它,我建议内存流使用较小的缓冲区(256B - 1KB),文件流使用中等大小的缓冲区(10KB)。您还可以使其取决于源流的大小,例如 10%,大小限制为 1MB 左右。

对于文件,缓冲区越大,复制操作越快(在一定程度上),但安全性较低。对于内存流,小缓冲区几乎与大缓冲区一样有效,但在内存上更容易(如果您复制很多)。

【讨论】:

  • 你是对的。但我需要知道缓冲区大小如何影响内存使用和性能。
  • 然后做一些测试。如果您复制很多并且希望保持较低的内存使用率,请先使用小缓冲区,然后测试,增加缓冲区并再次测试以查看影响。继续这样做,直到你的最佳位置。
猜你喜欢
  • 2011-09-13
  • 1970-01-01
  • 1970-01-01
  • 2016-09-01
  • 1970-01-01
  • 2022-11-11
  • 1970-01-01
  • 2019-10-14
  • 1970-01-01
相关资源
最近更新 更多