HttpWebResponse响应流的最佳缓冲区大小

10

使用HttpWebResponse.GetResponseStream()获取流时,最佳缓冲区大小是多少?

在线示例的缓冲区大小从256字节到5K字节不等。这是为什么?我猜缓冲区大小可能与情况有关。如果是这样,那么使用哪种类型的缓冲区大小的情况是什么?

谢谢。

3个回答

7

实际上,这并不是非常重要。

当然,如果您使用非常小的缓冲区,则可能需要通过层逐层进行一些额外的调用以获取字节(尽管流很可能会进行至少一些缓冲 - 我不知道它的默认值是什么)。同样,如果您使用非常大的缓冲区,则会浪费一些内存并引入一些碎片化。由于您显然正在执行 IO 操作,在调整缓冲区时获得的任何时间都将被 IO 时间所主导。

一般而言,我会选择2048(2k)到8192(8k)之间的二次幂。只需确保如果您使用85,000字节或更大的缓冲区,则知道自己在做什么(那时它是“大对象”,并受不同的 GC 规则约束)。

事实上,比缓冲区大小更重要的是您持有它的时间。对于大对象堆之外的对象,GC 处理非常短寿的对象(Gen 0 集合速度快)或非常长寿的对象(Gen 2)非常出色。在释放之前存活到 Gen 1 或 2 的对象相对更加昂贵,通常比缓冲区的大小更值得您花时间担心。

最后一点:如果您认为由于使用的缓冲区大小而导致性能问题,请测试。虽然不太可能,但谁知道,也许您的操作系统版本、网络硬件和驱动程序发布与某些特定大小的缓冲区存在奇怪的问题。


1
非常有用的帖子,但我认为你是指8192?2的幂-> 2048、4096、8192(8k)。 - Derrick

3
我的经验是,实际情况取决于你正在做什么,但通常在1024-4096字节范围内(1-4KB即2的幂)的任何内容都可以给我相当的性能(其中4KB是我见过的“最佳”数字)。
基本上,您需要一个足够大的缓冲区,以便您不必从流中不必要地读取数据,但又不要太大,以至于您降低了收益。如果您的缓冲区太大(~ MB),那么您将增加内存缓存未命中的次数,这可能会实际上降低性能。当然,这在实际的硬件(总线速度、缓存大小等)上有很大的变化,但我已经看到过4MB缓冲区比4KB缓冲区慢的情况(两种情况都具有长寿命,因此GC不是问题)。
正如Jonathan所指出的,在尝试过早进行优化之前,请测试您当前的实现。

2

当缓冲区大小过小时,我遇到了问题。我已经测试并验证了缓冲区大小不应该设置为小值。在我的例子中,我将其设置为2048,与没有下载分段的Firefox相比(和我的一样),下载速度变得非常慢。

当我将其设置为较大的大小409600后,下载速度明显加快。我认为额外的调用会产生开销或其他使下载变慢的原因。也许在网络层面上,缓冲区超过了您的缓冲区大小,所以TCP需要请求重新发送数据包?(只是猜测,因为我不知道TCP如何工作),但是小缓冲区大小肯定会减慢我的下载速度。我通过运行Firefox默认下载(没有添加和分段)和使用我的类进行测试,两者差别很大。

现在下载速度快多了,每次循环它会读取约200000字节(200Kb),因为这里的连接非常快,但是在运行两个线程后,速度会变慢,可能需要与另一个线程共享。


在上传一个大文件(2GB)的情况下,我也遇到了同样的问题:使用更大的缓冲区可以使上传速度更快。 - Mickael V.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接