В настоящее время я разрабатываю приложение для 3D-графики, используя JOGL (привязка Java OpenGL). Короче говоря, у меня огромный ландшафтный двоичный файл. Из-за его размера, я должен потопить рельефные куски во время выполнения. Поэтому мы явно рассматриваем проблему произвольного доступа. Я уже закончил первые (и грязные :)) реализации (возможно, это многопоточный), где я использую глупый подход ... Вот инициализации этого:Поток файлов в Java
dataInputStream = new DataInputStream(new BufferedInputStream(fileInputStream,4 * 1024);
dataInputStream.mark(dataInputStream.available());
И когда я нужно читать (поток) специальный кусок (я уже знаю его «смещение» в файле) я выступаю следующий (позор мне :)):
dataInputStream.reset();
dataInputStream.skipBytes(offset);
dataInputStream.read(whatever I need...);
Поскольку я имел мало опыта, который был первым вещь, о которой я мог думать :) Итак, до сих пор я прочитал 3 полезные и довольно интересные статьи (я предлагаю вам их прочитать, возможно, если вас интересует эта тема)
Byte Buffers and Non-Heap Memory - мистер Грегори, кажется, быть грамотным в Java NIO.
Java совет: Как читать файлы быстро [http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly] - Это интересный тест.
Статьи: Настройка производительности Java I/O [http://java.sun.com/developer/technicalArticles/Programming/PerfTuning/] - Простые рекомендации Sun, но, пожалуйста, прокрутите вниз и посмотреть на " Случайный доступ "; они показывают простую реализацию RandomAccessFile (RAF) с улучшением самобуферизации.
Г-н Грегори предоставляет несколько файлов * .java в конце своей статьи. Один из них - это бенчмаркинг между FileChannel + ByteBuffer + Mapping (FBM) и RAF. Он говорит, что он заметил 4-кратное ускорение при использовании FBM по сравнению с RAF. Я побежал этот тест в следующих условиях:
- Смещение генерируется случайным образом (в области видимости файла, например 0 - file.length()..); (Например место доступа.).
- Размер файла: 220MB;
- 1 000 000 доступов (75% считывает и 25% записи)
результаты были ошеломляющими:
~ 28 сек для RAF! ~ 0.2 сек. Для FBM!
Однако его реализация RAF в этом тесте не имеет самообучения (в третьей статье рассказывается об одном), поэтому я предполагаю, что это метод «RandomAccessFile.seek», который так сильно снижает производительность.
Ok, теперь после всех тех вещей, которые я узнал есть один вопрос и 1 дилемма :)
Вопрос: Когда мы картографирования файл с помощью «FileChannel.map» делает Java скопировать весь файл содержимое в MappedByteBuffer? Или это просто подражает ему?Если он копирует, то использование метода FBM не подходит для моей ситуации, не так ли?
Дилемма: В зависимости от ваших ответов на вопрос ...
Если отображение копирует файл, то кажется, что у меня есть только два возможных решения, чтобы пойти: RAF + само-буферные (один из 3-й статьи) или использовать позицию в FileChannel (не с картографированием) ... Какой из них лучше?
Если сопоставление не копирует файл, у меня есть 3 варианта: два предыдущих и Сам FBM.
Редактировать: Вот еще один вопрос. Некоторые из вас говорят, что сопоставление не копирует файл в MappedByteBuffer. Итак, почему я не могу сопоставить 1GB-файл, тогда я получаю сообщение «не удалось отобразить» ...
PS Я хотел бы получить отложенный ответ с советами, так как я не могу найти согласованную информацию по этой теме в Интернете.
Спасибо :)
Если вы говорите, что MappedByteBuffer является указателем на HD, то как он достигает таких хороших результатов в бенчмаркинге? Единственная возможная функция ускорения в IO, которую я лично знаю, - ДОСТУП К ДИСКУ КАК МЕНЬШЕ КАК ВОЗМОЖНО, и единственным решением здесь является буферизация. Опять же, если вы достаточно грамотны в этом отношении, будьте более подробными. –
@Haroogan Я цитирую из этой статьи: «разница почти полностью связана с переключением контекста ядра» – someguy
Вы, должно быть, шутите, обращаясь к javadoc, не так ли? Coz, нет никакой конкретной информации, о которой я прошу. У меня до сих пор нет прямых ответов или правильных идей и комментариев о возможных решениях. –