О выборе размера буфера в HttpWebRequest GetResponseStream

73
4

var h = (HttpWebRequest)WebRequest.Create(url);
using (var hr = (HttpWebResponse)(await h.GetResponseAsync()))
{
using (var s = hr.GetResponseStream())
{
using (var f = new FileStream(saveTo, FileMode.Create, FileAccess.Write, FileShare.None))
{
int bytesCount = 0;
byte[] buf = new byte[2048]; //<------------------------------

while ((bytesCount = await s.ReadAsync(buf, 0, buf.Length)) > 0)
{
await f.WriteAsync(buf, 0, bytesSize);
// Update UI : downloaded size, percent,...
}
}
}
}

Я пишу пользовательский интерфейс обновления поддержки загрузчика (ObservableCollection of thounsands items - Batch download), когда процесс загрузки изменяется и возобновляется загрузка, но не поддерживается многосегментная загрузка (поскольку каждый размер элемента обычно <10 МБ).
Я запускаю около 5-20 параллельных загрузок. Какой размер буфера подходит для этого случая (полезно как для обновления пользовательского интерфейса, так и для загрузки)?

спросил(а) 2021-01-14T00:28:42+03:00 2 недели назад
1
Решение
87

Вы хотите использовать размер буфера, который кратен размеру страницы ОС, потому что это гранулярность для записи на диск и страницы в памяти. Использование чего-либо меньшего, чем размер страницы ОС, будет субоптимальным.

Страницы ОС обычно составляют 4096 байт. Размер буфера по умолчанию для FileStream, используемый при отсутствии размера буфера во время его построения, также составляет 4096 байт.

Для дискового ввода-вывода обычно предпочтительнее иметь буфер, который несколько больше (32-128 КБ).

В вашем сценарии, используя максимум 20 одновременных загрузок, если бы вы использовали размер буфера 32 или 64 КБ, для этого потребовалось бы только 640 КБ или 1,2 МБ памяти, поэтому это явно жизнеспособные варианты.

Предположим, вы находитесь в США, где средняя скорость загрузки составляет 23 Мбит/с и 12 Мбит/с для широкополосных и мобильных устройств соответственно, тогда, если вы используете буферы 64 КБ (1,2 МБ для 20 одновременных загрузок), вы можете обновить интерфейс для каждого из 20 скачиваний несколько раз в секунду.

Итак, используйте не менее 32 - 64 КБ буферов.

Одна вещь, о которой нужно заботиться, - это не постоянно выделять новые байт-буферы, а перерабатывать эти буферы с фиксированным размером, используя пул буферов

ответил(а) 2021-01-14T00:28:42+03:00 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема