У меня есть метод, который создает MessageDigest (хэш) из файла, и мне нужно сделать это для большого количества файлов (> = 100 000). Насколько большой я должен сделать буфер, используемый для чтения из файлов, чтобы максимизировать производительность?
Почти все знакомы с основным кодом (который я повторю здесь на всякий случай):
MessageDigest md = MessageDigest.getInstance( "SHA" );
FileInputStream ios = new FileInputStream( "myfile.bmp" );
byte[] buffer = new byte[4 * 1024]; // what should this value be?
int read = 0;
while( ( read = ios.read( buffer ) ) > 0 )
md.update( buffer, 0, read );
ios.close();
md.digest();
Каков идеальный размер буфера для максимизации пропускной способности? Я знаю, что это зависит от системы, и я почти уверен, что это зависит от операционной системы, файловой системы и жесткого диска, и, возможно, в миксе есть другое оборудование / программное обеспечение.
(Я должен отметить, что я немного новичок в Java, так что это может быть просто вызов Java API, о котором я не знаю.)
Редактировать: я не знаю заранее типов систем, на которых это будет использоваться, поэтому я не могу предположить много. (Я использую Java по этой причине.)
Редактировать: код выше пропускает такие вещи, как try..catch, чтобы сделать пост меньше
источник
Да, это, вероятно, зависит от разных вещей - но я сомневаюсь, что это будет иметь большое значение. Я предпочитаю выбирать 16К или 32К в качестве хорошего баланса между использованием памяти и производительностью.
Обратите внимание, что в коде должен быть блок try / finally, чтобы убедиться, что поток закрыт, даже если выдается исключение.
источник
В большинстве случаев это не так важно. Просто выберите хороший размер, например 4K или 16K, и придерживайтесь его. Если вы положительны , что это узкое место в вашем приложении, то вы должны начать профилирование , чтобы найти размер оптимален буфера. Если вы выберете слишком маленький размер, вы будете тратить время на дополнительные операции ввода-вывода и дополнительные вызовы функций. Если вы выберете слишком большой размер, вы начнете видеть много пропусков кэша, которые действительно замедлят вас. Не используйте буфер больше, чем ваш размер кэша L2.
источник
В идеальном случае у нас должно быть достаточно памяти для чтения файла за одну операцию чтения. Это было бы лучше всего, потому что мы позволяем системе управлять файловой системой, единицами распределения и жесткими дисками по желанию. На практике вам повезло знать размеры файлов заранее, просто используйте средний размер файла, округленный до 4 КБ (единица выделения по умолчанию в NTFS). И самое главное: создайте тест для тестирования нескольких вариантов.
источник
Вы можете использовать BufferedStreams / reader и затем использовать их размеры буфера.
Я полагаю, что BufferedXStreams использует 8192 в качестве размера буфера, но, как сказал Овидиу, вам, вероятно, следует запустить тест на целую кучу вариантов. Это действительно будет зависеть от файловой системы и конфигурации диска относительно того, каковы лучшие размеры.
источник
Чтение файлов с использованием JavaCIO FileChannel и MappedByteBuffer, скорее всего, приведет к решению, которое будет намного быстрее, чем любое решение, включающее FileInputStream. По сути, карта памяти больших файлов, и использовать прямые буферы для маленьких.
источник
В источнике BufferedInputStream вы найдете: private static int DEFAULT_BUFFER_SIZE = 8192;
Так что вы можете использовать это значение по умолчанию.
Но если вы сможете узнать больше информации, вы получите более ценные ответы.
Например, ваш adsl может иметь буфер 1454 байта, потому что полезная нагрузка TCP / IP. Для дисков вы можете использовать значение, соответствующее размеру блока вашего диска.
источник
Как уже упоминалось в других ответах, используйте BufferedInputStreams.
После этого, я думаю, размер буфера не имеет большого значения. Либо программа связана с вводом / выводом, и увеличение размера буфера по сравнению с BIS по умолчанию не окажет большого влияния на производительность.
Или программа связана с процессором внутри MessageDigest.update (), и большая часть времени не тратится на код приложения, поэтому его настройка не поможет.
(Хм ... с несколькими ядрами, потоки могут помочь.)
источник
1024 подходит для широкого спектра обстоятельств, хотя на практике вы можете увидеть лучшую производительность с большим или меньшим размером буфера.
Это будет зависеть от ряда факторов, включая размер блока файловой системы и аппаратное обеспечение процессора.
Также обычно выбирают степень 2 для размера буфера, так как большинство базового оборудования структурировано с блоком fle и размерами кэша, которые являются степенью 2. Классы Buffered позволяют указывать размер буфера в конструкторе. Если ничего не указано, они используют значение по умолчанию, которое является степенью 2 в большинстве JVM.
Независимо от того, какой размер буфера вы выберете, наибольшее увеличение производительности вы увидите при переходе от небуферизованного к буферизованному доступу к файлам. Регулировка размера буфера может немного улучшить производительность, но если вы не используете очень маленький или очень большой размер буфера, это вряд ли окажет существенное влияние.
источник