Умная буферизация в среде с ограниченным объемом памяти Java - PullRequest
2 голосов
/ 14 июля 2011

Уважаемые StackOverflowers,

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

Стандартный способ сделать это - заполнить ~ 50% доступной памяти каким-либо буферизованным объектом (BufferedInputStream и т. Д.), А затем передать целые числа из буферизованного объекта в массив целых чисел (который занимает остальные свободного места) и отсортировать целые числа в массиве. Сохраните отсортированный блок обратно на диск, повторяйте процедуру, пока весь файл не будет разбит на отсортированные блоки, а затем объедините блоки вместе. Стратегия сортировки блоков использует только 50% доступной памяти, поскольку данные по существу дублируются (50% для кеша и 50% для массива, пока они хранят одни и те же данные).

Я надеюсь, что смогу оптимизировать этот этап алгоритма (сортировку блоков), написав свой собственный буферизованный класс, который позволяет кэшировать данные прямо в массив int, чтобы массив мог занимать все свободное пространство, а не только На 50% это уменьшит число обращений к диску на этом этапе в 2 раза. Дело в том, что я не уверен, с чего начать.

EDIT: По сути, я хотел бы найти способ заполнить массив целых чисел, выполнив только одно чтение файла. Другое ограничение - массив должен использовать большую часть свободной памяти.

Если какое-либо из сделанных мною утверждений неверно или, по крайней мере, кажется, поправьте меня,

любая помощь приветствуется,

Привет

Ответы [ 3 ]

2 голосов
/ 14 июля 2011

когда вы говорите «ограниченный», насколько ограниченный ... <1 МБ <10 МБ <64 МБ?</p>

Это имеет значение, так как на самом деле вы не получите большой выгоды от большого BufferedInputStreams, в большинстве случаев достаточно значения по умолчанию 8192 (JDK 1.6), а увеличение обычно не так уж многоРазница.

Использование меньшего BufferedInputStream должно дать вам почти все кучи для создания и сортировки каждого чанка перед записью их на диск.

1 голос
/ 14 июля 2011

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

Во-вторых, одно слово (хорошо, термин) кричит в моей голове, когда я слышу это: внешняя сортировка ленты .В первые компьютерные дни (т.е. каменный век) данные основывались на лентах, и было очень трудно сортировать данные, распределенные по нескольким лентам.Это очень похоже на вашу ситуацию.И действительно, сортировка слиянием была наиболее часто используемой сортировкой в ​​те дни, и, насколько я помню, у Knuths TAOCP была хорошая глава об этом.Может быть несколько полезных советов о размере кэшей, буферов и тому подобного.

1 голос
/ 14 июля 2011

Возможно, вы захотите заглянуть в библиотеки Java NIO , в частности Файловые каналы и Int Buffers .

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