Какой размер буфера памяти лучше всего выделить для загрузки файла из Интернета? - PullRequest
12 голосов
/ 21 октября 2011

Какой размер буфера памяти лучше выделить для загрузки файла из Интернета? Некоторые из образцов сказали, что это должно быть 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);
}

Ответы [ 5 ]

16 голосов
/ 12 декабря 2014

Я протестировал чтение текстового файла размером 1484 КБ, используя прогрессивные степени двойки (размеры 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
5 голосов
/ 21 октября 2011

Используйте не менее 4 КБ.Это нормальный размер страницы для Windows (то есть гранулярность, при которой сама Windows управляет памятью), что означает, что распределителю памяти .Net не нужно разбивать страницу размером 4 КБ на выделения размером 1 КБ.

Конечно,использование блока размером 64 КБ будет быстрее, но лишь незначительно.

1 голос
/ 12 ноября 2014

У меня проблема с подключением к удаленной машине при использовании буфера 64 КБ при загрузке с iis.

Я решил проблему, подняв буфер до 2M

1 голос
/ 21 октября 2011

2k, 4k или 8k - хороший выбор. Неважно, сколько будет размер страницы, изменение скорости будет действительно незначительным и непредсказуемым.

Прежде всего, память C # может быть перемещена, C # использует компактный сборщик мусора поколений. Информация о том, где будут размещаться данные, отсутствует.

Во-вторых, массивы в C # могут быть сформированы из несмежной области памяти! Массивы хранятся непрерывно в виртуальной памяти, но непрерывная виртуальная память не означает непрерывную физическую память.

В-третьих, структура данных массива в C # занимает на несколько байтов больше, чем сам контент (он хранит размер массива и другую информацию). Если вы выделите размер страницы в байтах, использование массива переключит страницу почти всегда!

Я думаю, что оптимизация кода с использованием размера страницы может быть неоптимизацией.

Обычно массивы C # работают очень хорошо, но если вам действительно нужно точное распределение данных, вам нужно использовать закрепленные массивы или распределение Маршала, но это замедлит сборщик мусора.

Использование маршала и небезопасного кода может быть немного быстрее, но на самом деле это не стоит усилий.

Я бы сказал, что лучше использовать массивы, не слишком задумываясь о размере страницы. Используйте 2К, 4К или 8К буферов.

0 голосов
/ 21 октября 2011

В некоторых случаях вы можете узнать (или узнать, или взломать в отладчике и, следовательно, узнать, хотя и не устойчивым к изменениям) размер буфера, используемого потоком (ами), в который вы пишете или чтение из. В этом случае это даст небольшое преимущество, если вы подберете этот размер или не достигнете его, если один буфер будет кратным другому.

В противном случае 4096, если у вас нет другой причины (например, требуется небольшой буфер для быстрой обратной связи с пользовательским интерфейсом) по уже указанным причинам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...