Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Java: Общие вопросы > RandomAccessFile Скорость записи |
Автор: Mirkes 19.3.2014, 19:44 | ||
Мне нужен быстрый доступ к отдельным значениям в большом бинарном файле. Решил использовать RandomAccessFile. Тут же возникла проблема - запись файла из старого формата в новый работает с потрясающей скоростью. Вот полный текст перекодировки:
Файл большой nRow=8082, nCol=14090. Это спутниковый снимок в некоем странном текстовом формате. В методе getData происходит чтение другого, текстового, файла и конвертация в числовую форму. pb не работает с файлами. В том виде, в котором программа приведена выше время обработки одного файла 38 минут Если закомментировать строку с raf то время работы 19 секунд. Запись производится подряд. Конечно, пишется 869М, но не с такой же тормознутостью. Или это свойство RandomAccessFile? К сожалению после завершения записи файла мне надо дописать пару значений в начало файла, так что RandomAccessFile вроде по существу. Что посоветуете? Как ускорить работу? |
Автор: Pawl 19.3.2014, 21:31 | ||
Не знаю, будет ли так проще - вы можете записать перекодированные данные в один временный файл, пару значений - в другой, а затем считывать из этих файлов данные и писать их в итоговый файл. Есть в пакете io класс SequenceInputStream, он может читать из нескольких файлов по очереди. Понятно, так потребуется больше места на диске, но скорость будет выше. |
Автор: Mirkes 19.3.2014, 22:02 | ||||||
To Pawl Спасибо, приблизительно это и реализовал. Фактически я сделал запись в DataOutputStream а потом переоткрыл его как RandomAccessFile и дописал оставшиеся два значения. Открывал как "rw". Из документации мне показалось, что это быстрее чем rws и rwd. В результате замены типа выходного потока время уменьшилось до 6.25 минуты, что уже приемлемо (нужно сконвертировать 12 файлов). Однако мне все равно не понятно, почему при файле открытом как
запись идет в 5 раз медленнее чем в файле, открытом как
Кстати только что заметил, что и ПОСЛЕДОВАТЕЛЬНОЕ чтение из файла открытого
идет жутко медленно. Гораздо медленнее чем из текстового файла со все его парсингом и т.п. Засек точное время. Даже с заменой способа чтения на DataInputStream чтение всего файла заняло около 10 минут. Мне просто интересно, это принципиальная особенность файлов прямого доступа? Или так сильно тормозит приведение каждого double к некоему переносимому стандарту java при записи и соответственно обратное преобразование при чтении? Попробую сформулировать задачу иначе. Есть большой текстовый файл (14000 столбцов и 8000 строк, что-то чуть больше 100 миллионов значений). Таких файлов 12. К файлу есть два варианта запроса. 1. Прочитать все данные для формирования картинки на экране. Нужно пару раз на каждый файл. В принципе если плюнуть на все и просто парсить текстовый файл то это займет около 1 минуты. Не фонтан, но терпимо. 2. Указать значение с определенными координатами. Порядка 30,000 запросов на файл при условии, что повторных обработок не будет. Ограничение на хранение массива в памяти очевидно. На массив нужно что-то около 800М памяти. Исходя из второй задачи я предполагал, что конвертация в бинарный файл даст приличный выигрыш при дальнейших запросах, однако получается, что для создания картинки точно лучше читать прямо текстовый файл (1 минута против 10 из бинарного). К сожалению пока не закончил вторую часть и не могу сказать сколько займет выполнение тех 30,000 запросов по координатам. Как наиболее организовать быструю работу с файлом? Может без интерфейсов DataOutput и DataInput работа с файлом пойдет быстрее? Переносить конвертированные файлы я не собираюсь. Таким образом окончательная формулировка вопроса: Какой тип работы с файлами Вы порекомендуете для этой задачи? |
Автор: LSD 20.3.2014, 11:29 | ||
Я бы рекомендовал memory mapped file.
|
Автор: Mirkes 20.3.2014, 12:35 | ||||
Спасибо. Попробую. Попробовал и ничего не понял. Вот код
размер файла 911 003 096 байт. Файл создан именно такого размера. В ответ получил
Программа запускалась с опцией -Xmx1600m Так что даже в heap должно быть достаточно памяти для отображения, хотя, как я прочитал, память выделяется за пределами heap. Может нужно указать еще какие-то опции для взятия памяти? |
Автор: LSD 21.3.2014, 11:12 |
Для memory mapped file не требуется памяти в полном объеме. Поэтому размер хипа как раз не важен. Я думаю скорее всего закончилось адресное пространство процесса, и файл просто некуда мапить. У тебя ОС и JVM какие 32/64 битные? |
Автор: Mirkes 21.3.2014, 11:39 |
ОС Windows 7 Enterprice SP1 64bit RAM 8G IDE JDeveloper 11.1.2.4 Java Platform 1.6.0_24 JRE 1.5.0_45 32bit Забавно, JDK и JRE разные. JRE обновляется автоматически, а JDK видимо нужно обновлять вручную |
Автор: LSD 21.3.2014, 12:57 |
У 32-х битного процесса адресное пространство 2Gb. У тебя файл 900Mb, да еще и куча 1600Mb, явно больше 2Gb. |
Автор: Mirkes 21.3.2014, 13:44 |
Если я правильно понял, то воспользоваться отображенными файлами я смогу только перейдя на 64bit-ую Java? Спасибо за помощь. |
Автор: Mirkes 21.3.2014, 17:35 |
Собственно это я и имел в виду. Поскольку я отображаю сопоставимые по размеру картинки, то памяти на maping файла уже не остается. Но картинки мне нужны позарез, так что придется смириться с медленной работой файла или переходить на 64 бита. Еще раз спасибо. |
Автор: Pawl 27.3.2014, 12:48 | ||
Пардон, что пишу в закрытую тему, нашел способ добавить в начало файла данные при помощи java.nio. Если вам интересно, можете попробовать, протестировать скорость и т. д. ![]()
|
Автор: Mirkes 27.3.2014, 13:18 | ||
Спасибо. На самом деле это интересно, но свою проблему я решил. Не быстро, но решил. Основной ступор был в том, что поднять на мозги весь файл было слишком накладно. А когда я пробовал еще что-то делать получал переполнение памяти. Посему я и хотел получить прямой доступ. А прямой доступ без отображения в память оказался очень медленным. А на отображение в память - нет места. И получил замкнутый круг. На самом деле я решил достаточно просто - сначала записал без прямого доступа положив на место пока неизвестных параметров заглушки, потом переоткрыл файл с прямым доступом и записал вычисленные параметры на место. Далее использовал прямой доступ. Когда появится время (если появится) попробую поэкспериментировать с разными типами файлового ввода=вывода и их скоростью. Спасибо за совет. |