Оптимальный размер буфера зависит от нескольких факторов: размер блока файловой системы, размер кэша ЦП и задержка кэша.
Большинство файловых систем сконфигурировано для использования блоков размером 4096 или 8192. Теоретически, если вы конфигурируете размер буфера таким образом, что вы читаете на несколько байтов больше, чем блок диска, операции с файловой системой могут быть крайне неэффективными (т.е. если вы сконфигурировал ваш буфер для чтения 4100 байт за раз, каждое чтение потребовало бы 2 блока чтения файловой системой). Если блоки уже находятся в кеше, вы платите цену RAM -> L3 / L2 латентность кеша. Если вам не повезло, а блоки еще не находятся в кеше, вы также платите за задержку диска -> ОЗУ.
Вот почему вы видите большинство буферов, размер которых равен степени 2 и обычно больше (или равен) размеру блока диска. Это означает, что одно из ваших потоковых чтений может привести к нескольким дисковым чтениям блоков - но эти чтения всегда будут использовать полный блок - без потраченных чтений.
Теперь, это типично смещено в типичном сценарии потоковой передачи, потому что блок, который читается с диска, все еще будет в памяти, когда вы нажмете следующее чтение (в конце концов, мы делаем последовательные операции чтения) - так что вы заводите при следующем чтении оплачивается цена задержки ОЗУ -> L3 / L2, но не задержка диска -> ОЗУ. С точки зрения порядка величины задержка диска-> ОЗУ настолько медленная, что значительно перекрывает любую другую задержку, с которой вы можете иметь дело.
Итак, я подозреваю, что если вы запустили тест с разными размерами кэша (сам этого не делал), вы, вероятно, обнаружите большое влияние размера кэша вплоть до размера блока файловой системы. Кроме того, я подозреваю, что все выровняется довольно быстро.
Есть целая тонна условий и исключений здесь - сложность системы на самом деле довольно ошеломляющая (просто получить ручку на L3 -> передает кэш L2 ум умопомрачительно сложен, и он меняется с каждым типом процессора).
Это приводит к ответу «реального мира»: если ваше приложение на 99%, установите размер кэша на 8192 и продолжайте (еще лучше, выберите инкапсуляцию вместо производительности и используйте BufferedInputStream, чтобы скрыть детали). Если вы находитесь в 1% приложений, которые сильно зависят от пропускной способности диска, создайте свою реализацию, чтобы вы могли поменять различные стратегии взаимодействия с дисками и предоставили ручки и наборы, чтобы позволить вашим пользователям тестировать и оптимизировать (или придумать некоторые самооптимизирующаяся система).