LINUX.ORG.RU

Как определить оптимальный размер буфера при чтении файла?

 , ,


0

3

Изучаю Java по 9-у изданию полного руководства Шилдта и хочу написать программу в качестве проекта для обучения, первый этап это чтение данных. И тут я решил немного углубиться в тему, т.к. данные могут иметь большой объём. В таком случае рекомендуют использовать буферизированные потоки ввода\вывода для уменьшения операций чтения, это понятно, но каким сделать размер буфера? У Шилдта фигурирует число 8192. Поискав в интернете я нашёл как советы использовать это число и не париться, так и определить размер буфера исходя из размера блока файловой системы и размера кэша жёсткого диска. В общем я решил задать свои вопросы здесь: каким же должен быть размер буфера, есть ли способы сделать программу переносимой(чтобы производительность операций с диском была одинаково высокой и на других машинах)? Ну и вопрос новичка — что лучше использовать io или nio?

Определить размер кэша и блока из java может быть не так просто (особенно переносимым способом). 8192 хорошее среднее значение. Раньше размер полезных данных в физическом секторе был 512 байт, сейчас 4096. Оба кратны 8192, а то что оно больше будет сглажено ядром и объединением физических секторов в блоки/кластеры. Я бы просто 8192 и использовал.

xaizek ★★★★★
()

Универсального числа нет, для каждой ситуации будет свой размер оптимальным. Если тебе важно выжимать последние проценты — делай этот размер конфигурируемым. А так — 4k, 8k, 64k нормальные варианты. Разница будет единицы процентов. Можешь потестировать с помощью dd, параметр bs.

Legioner ★★★★★
()

что лучше использовать io или nio?

Для блокирующего — io. Для неблокирующего — nio (а ещё лучше надстройку вроде xnio). Для манипуляций файлами имхо удобней nio и функционала у него больше. Для чтения/записи файлов в 99.999% достаточны именно блокирующие вызовы, если что.

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 2)
Ответ на: комментарий от xaizek

Определить размер кэша и блока из java может быть не так просто (особенно переносимым способом).

А что, в Яве нет stat(2)?

akk ★★★★★
()
Ответ на: комментарий от akk

Не помню, давно не писал на ней. Вроде что-то подобное было, но там только размер блока может быть.

Поискал и кажется кое-что добавили в 7-ой версии, но не вижу там размера блока (доки).

xaizek ★★★★★
()

Начни лучше с английского и умением пользоваться гуглом. А вот и ответ http://stackoverflow.com/a/10698421/3089918

А вот еще к сведению http://stackoverflow.com/a/237038/3089918 А еще лучше изучить методы и реализацию java.nio.file.Files и на базе его примера городить свои читатели, если readAllBytes не устраивает и нужно внедрять собственный хандлер во время чтения.

В противном случае твои читатели будут работать через задницу. Недавно столкнулся с тем, что в Undertow в IOUtils читатели кривые и не умеют правильно читать UTF8 с небольшими вхождениями кирилицы.

foror ★★★★★
()
Последнее исправление: foror (всего исправлений: 2)
Ответ на: комментарий от foror

А вот, кстати и этот индуский метод из Undertow:

    public static String readFile(InputStream file) {
        try (BufferedInputStream stream = new BufferedInputStream(file)) {
            byte[] buff = new byte[1024];
            StringBuilder builder = new StringBuilder();
            int read;
            while ((read = stream.read(buff)) != -1) {
                builder.append(new String(buff, 0, read));
            }
            return builder.toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
foror ★★★★★
()
Ответ на: комментарий от foror

Гуглить я гуглил и кроме той ссылки, что Вы указали, я могу накидать других, одни разделяют эту точку зрения, другие говорят, что надо определять размер блока файловой системы, кэша жёсткого диска и может что-нибудь ещё. Я, собственно, хотел спросить ни помощи в гуглении, а поделиться опытом тех, кто решал подобные задачи, есть ли средства для определения выше указанных параметров в системе, в которой запускается программа, а главное есть ли смысл или при этом можно выиграть только доли процента и достаточно использовать 8192.

flyshoot
() автор топика
Ответ на: комментарий от Legioner

А так — 4k, 8k, 64k нормальные варианты. Разница будет единицы процентов.

Производительности? Зато при использовании слишком маленького размера буфера нагрузки на процессор будет на процентов 20 больше.

gag ★★★★★
()

использовать это число и не париться

Звучит разумно. Физически данные будут вычитываться размером в «read ahead». Можно посмотреть текущее значение в 512-байтных блоках командой blockdev --report, колонка RA. Обычно это около 128К, но может быть и другое (особенно на RAID/LVM)

Т.е. эти 8К это просто размер «окна», при небольших значениях размер этого буфера к скорости считывания имеет довольно условное отношение

Deleted
()
Ответ на: комментарий от flyshoot

а главное есть ли смысл или при этом можно выиграть только доли процента

Люди с действительно быстрыми медиа получают выигрыш в 156..442 процента! Но в coreutils всё ещё определяют оптимум статически: минимум 128 KB.

gag ★★★★★
()
Ответ на: комментарий от gag

в coreutils всё ещё определяют оптимум статически: минимум 128 KB.

Где там а) статически и б) минимум 128К?

akk ★★★★★
()
Ответ на: комментарий от akk

Если пройти по ссылке, которую я привёл, то можно увидеть:

enum { IO_BUFSIZE = 128*1024 };
static inline size_t
io_blksize (struct stat sb)
{
  return MAX (IO_BUFSIZE, ST_BLKSIZE (sb));
}

gag ★★★★★
()
Ответ на: комментарий от foror

Под виндой всё работает же :) Метод плох ещё и потому, что использует платформо-зависимую кодировку. А где этот метод вообще используется?

Legioner ★★★★★
()
Ответ на: комментарий от akk

Если код не понятен, разжёвываю по-русски:

а) статически

enum { IO_BUFSIZE = 128*1024 }: IO_BUFSIZE - константа 128 КБ
ST_BLKSIZE (sb) - константа для всей файловой системы: 4 КБ .. несколько МБ (размер кластера)

б) минимум 128К

MAX (IO_BUFSIZE, ST_BLKSIZE (sb)) =
= максимум (IO_BUFSIZE, ST_BLKSIZE (sb)) =
= максимум (128 КБ, 4 КБ .. несколько МБ) =
= минимум 128 КБ
gag ★★★★★
()
Ответ на: комментарий от gag

ST_BLKSIZE (sb) - константа для всей файловой системы

А, для разных ФС размер буфера таки разный. Это называется статически. Буду знать.

максимум (128 КБ, 4 КБ)
минимум 128 КБ

Наибольшая из двух величин называется минимумом. Тоже буду знать

Благзаин.

akk ★★★★★
()
Ответ на: комментарий от Legioner

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

foror ★★★★★
()

Самый интересный тред с тегом #джава за последнее время.

cdshines ★★★★★
()
Ответ на: комментарий от flyshoot

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

Ну и? В накиданых ссылках про то и речь. Хочешь получить перформанс достань инфу о железе и подкрути параметры в рантайме. Если же тебе нужно просто конфиги читать или в кеш что-нибудь закинуть, то не один ли хрен, если ты не гугл или фейсбук?

foror ★★★★★
()
Последнее исправление: foror (всего исправлений: 1)
Ответ на: комментарий от foror

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

foror ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.