从Internet下载文件时分配的最佳内存缓冲区大小是多少?

本文关键字:缓冲区 多少 内存 最佳 下载 Internet 文件 分配 | 更新日期: 2023-09-27 18:11:51

从Internet下载文件分配的最佳内存缓冲区大小是多少?有些样品说应该是1K。我需要知道为什么会这样?如果我们下载一个小的.PNG和一个大的.AVI有什么区别呢?

Stream remoteStream;
Stream localStream;
WebResponse response;
try
{
    response = request.EndGetResponse(result);
    if (response == null)
        return;
    remoteStream = response.GetResponseStream();
    var localFile = Path.Combine(FileManager.GetFolderContent(), TaskResult.ContentItem.FileName);
    localStream = File.Create(localFile);
    var buffer = new byte[1024];
    int bytesRead;
    do
    {
        bytesRead = remoteStream.Read(buffer, 0, buffer.Length);
        localStream.Write(buffer, 0, bytesRead);
        BytesProcessed += bytesRead;
    } while (bytesRead > 0);
}

从Internet下载文件时分配的最佳内存缓冲区大小是多少?

无论如何,我测试了读取一个1484 KB的文本文件,使用2的渐进式幂(大小为2,4,8,16…)。我向控制台窗口输出了读取每个数据所需的毫秒数。早在8192年之后,似乎并没有太大的区别。以下是我在Windows 7 64位机器上的测试结果。

2^1 = 2 :264.0151
2^2 = 4 :193.011
2^3 = 8 :175.01
2^4 = 16 :153.0088
2^5 = 32 :139.0079
2^6 = 64 :134.0077
2^7 = 128 :132.0075
2^8 = 256 :130.0075
2^9 = 512 :133.0076
2^10 = 1024 :133.0076
2^11 = 2048 :90.0051
2^12 = 4096 :69.0039
2^13 = 8192 :60.0035
2^14 = 16384 :56.0032
2^15 = 32768 :53.003
2^16 = 65536 :53.003
2^17 = 131072 :52.003
2^18 = 262144 :53.003
2^19 = 524288 :54.0031
2^20 = 1048576 :55.0031
2^21 = 2097152 :54.0031
2^22 = 4194304 :54.0031
2^23 = 8388608 :54.003
2^24 = 16777216 :55.0032

至少使用4KB。这是Windows的正常页面大小(即Windows本身管理内存的粒度),这意味着。net内存分配器不需要将4KB的页面分解为1KB的分配。

当然,使用64KB的块会更快,但只是稍微快一点。

2k、4k或8k都是不错的选择。页面大小是多少并不重要,速度的变化将是真正的边际和不可预测的。

首先,c#内存是可以移动的,c#使用了一个压缩分代垃圾收集器。没有任何关于数据将被分配到哪里的信息。

第二,c#中的数组可以由不连续的内存区域组成!数组连续存储在虚拟内存中,但是连续的虚拟内存并不意味着连续的物理内存。

第三,c#中的数组数据结构比内容本身多占用一些字节(它存储数组大小和其他信息)。如果您分配页面大小的字节数,使用数组几乎总是会切换页面!

我认为使用页面大小优化代码可能是一种非优化。

通常c#数组执行得很好,但是如果你真的需要精确的数据分配,你需要使用固定数组或Marshal分配,但是这会减慢垃圾收集器的速度。

使用封送分配和不安全代码可能会快一点,但真的不值得这么做。

我想说,最好只是使用你的数组,而不考虑太多的页面大小。使用2k、4k或8k缓冲区

我在从iis下载时使用64K缓冲区时远程机器关闭连接有问题。

我解决了将缓冲区提高到2M的问题

这也取决于硬件和范围。我的工作是云部署的工作负载,在服务器世界中,您可能会发现40G以太网卡,您可以假设mtu为9000字节。另外,你不希望以太网卡在每一帧都中断处理器。所以,忽略Windows/Linux内核中的中间角色,你应该选择更高的一到两倍:100 * 9000 ~~ 900kB所以我通常选择512KB作为默认值(只要我知道这个值不会超出下载的常规预期文件大小)

在某些情况下,您可以发现(或知道,或在调试器中进行hack,从而发现(尽管以非更改抵抗的方式)正在写入或读取的流所使用的缓冲区大小。在这种情况下,如果一个缓冲区是另一个缓冲区的整数倍,那么如果你匹配了这个大小,或者没有达到这个大小,将会有一点优势。

除非你有其他理由(例如,想要一个小的缓冲区来提供快速的UI反馈),否则