Оптимальный размер буфера для Stream

        public static bool AppendStream(Stream streamFrom, Stream streamTo)
        {
            long size = streamTo.Length;
			int bufferSize = 4096;
            byte[] buf = new byte[bufferSize];
            do
            {
                int bytesRead = streamFrom.Read(buf, 0, buf.Length);
                if (bytesRead <= 0)
                {
                    break;
                }
                streamTo.Write(buf, 0, bytesRead);
            } while (true);

            return streamTo.Length == size + streamFrom.Length;
        }

Подскажите оптимальный размер буфера для Stream. Он может быть либо локальным файлом, либо получен через HttpWebRequest. Есть ли верхний порог на размер буфера?

Обычно все ставят что-нибудь типа 4096 или 8192 )
Это вроде бы значения по умолчанию где-то в .NET.
Можно попробовать поизмерять свое приложение с разными значениями. Но значительная разница (ухудшение скорости) скорее всего может быть только если слишком маленький (типа 1) или большой.

Однажды, при склеивании файлов, я случайно поставил размер буфера равный размеру самого файла. Это примерно 8 мегабайт. То есть, читался и писался весь файл за один вызов. Всё нормально склеилось и быстро работало.
Но что если стрим будет получен через HttpWebResponse.GetResponseStream()? Есть же ограничение на размер сетевого пакета (какое-то маленькое, не помню точно). Или обёртка его игнорирует? :thinking:

Нет никакой связи между размером сетевого пакета и размером буфера в .Net-объекте Stream. Пакет сначала считывается в операционную систему, затем данные оттуда копируются в буфер в память процесса. В другую сторону в обратном порядке (разрезаясь на пакеты нужного размера).

А оптимальный размер я бы брал в зависимости от файловой системы. В линуксе это особенно наглядно на raid-маcсиве (stride size), например 65536KB chunk:

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

Верно, что размеры кластера раньше были 4 килобайта, или размер страницы в памяти процессоров на архитектуре Intel может быть 4 килобайта. Но какой смысл жаться и экономить? А страницы памяти и более крупные бывают, мегабайтные.
https://wiki.osdev.org/Paging

Есть еще одна проблема. Если делать синхронизацию на каждой итерации, то при размере буфера 8192 форма начинает тормозить. Приходится либо увеличивать буфер (прямо-пропорционально скорости передачи), либо делать синхронизацию каждые N итераций.
Какой способ лучше? :thinking:

Попробуй описать твою ситуацию так, чтобы было понятно другим людям. Форма это из Windows.Forms? При чём тут итерации? Как вообще вызывается код? Знаешь ли ты про класс BackgroundWorker ?

А что именно не понятно?

Да.

Передача данных из Stream в Stream происходит при помощи циклов. У циклов есть итерации.

Я про него слышал, но никогда не использовал. Чем он отличается от Task? Позволяет не делать синхронизацию?

Уточните вопрос.

“Синхронизация” это сообщение прогресса для UI из другого потока?
Ну так это нормально, не надо 100 раз в секунду его дергать.
Тут не буфер менять надо, а просто каким-либо способом реже обновлять UI. “Раз в N” итераций/миллисекунд, debouncing и т.д.

Я про него слышал, но никогда не использовал.

Словами Лаврова: “High time to learn”.

У тебя ответ от Web-сервера занимает время и блокирует event loop интерфейса. Из-за этого всё выглядит так, что интерфейс становится неотзывчивым.

“Синхронизация” это сообщение прогресса для UI из другого потока?

Может быть он вызывает это кусковое выкачивание по таймеру или ещё как?

Task это ж и есть способ создания потоков. (более новый, чем BW)

То есть, вычислять delta time каждую итерацию это нормально? :thinking:
Снимок экрана 2023-06-13 134118
Получается, программы, где есть настройки интервала обновления - так и работают? :thinking: Тут, кстати, буфер по-дефолту UInt16.MaxValue стоит и ему норм.
Выходит, если он не успеет перекинуть 65536 байт за 100 миллисекунд, то GUI не обновится?

Ну можно и что-то другое придумать, а так почему б нет.

Я так делал, заказчик жив и в Турции )

В данном случае видимо да.

Смотря как сделано и что значит буфер, но похоже да.

Офигеть :dizzy_face: Не знал, что у него есть исходники. Лет 7-10 назад очень хотелось поправить вывод в окне копирования :upside_down_face:
Кто, интересно, выложил? Я думал, они давно болт поклали. Последнее обновление, вроде, ажно до 2010 было :dizzy_face: