![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как лучше работать с 300-мегабайтным массивом ? [D7, WinME, WinXP]
Алекс А © (2004-06-21 02:45:00)Есть файл на диске "base1.bin" размером в 300 мегабайт, его надо загрузить в массив Base1 . Делают так :
NewFile := TFileStream.Create('base1.bin', fmOpenRead or fmShareDenyWrite) ;
try
NewFile.ReadBuffer(Base1, 300000000);
finally
NewFile.Free;
end;
Данные используются только для чтения. Загрузка длится более минуты. Хотелось бы, чтобы загрузка шла не сразу от и до, а как то постепенно, по мере обращения программы к отдельным частям массива, чтобы небыло этой минутной паузы. Можно ли это сделать ? Или как вообще лучше это организовать ?
MacroDenS (2004-06-21 20:05:00) [41]А вобще какой смысл так напрягать память и хард?
На кой тебе ворочить сразу 300 метров?
Лучше все же по чуть-чуть,
потому как ну загрузишь ты (пусть даже быстро) в память все 300 метров, а из памяти она в файл подкачки полезет...
Сделай что-то вроде метрового кэна, то что чаше загружается пусть сразу при запуске грузится, а остальное по мере необходимости пусть подгружается...
если ты за быстрый поиск бьешься, то здесь ты особо много не выиграешь...
ChainikDenis (2004-06-21 19:56:00) [42]А ведь можно сразу к контроллера диска обращаться и считывать сектора - это ваще класно будет. Занял под файл определенные сектора, и читаешь какие только нужны..
Digitman (2004-06-21 09:26:00) [43]
> Алекс А (21.06.04 05:03) [21]
> Задача не имеет простого решения. А
> делать сложные я небуду.
Имеет.
Решение в таких случаях - отказ от собственного контейнера данных и движка управления ими в пользу одной из готовых существующих СУБД. Любая сколь-либо серьезная СУБД имеет готовые механизмы и интерфейс быстрого индексированного доступа к записям в таблицах БД любого размера, при этом таблица не считывается целиком в память, образуя набор данных, а считывается только позиционируемый фрагмент (одна или несколько последовательно идущих записей)
Романов Р.В. (2004-06-21 08:38:00) [44]Очень простое решение. Доставай нужную информацию прямо из файла с помощью CreateFileMapping или TFileStream. О производительности позаботятся кэш windows и HDD
Fay (2004-06-21 08:12:00) [45]Таких задач не бывает - "надо миллион раз в секунду кидаться в произвольное место 300-мегабайтного массива (чего-то?)".
Что на самом деле надо сделать, раз ты дошёл до такой жизни?
Алекс А (2004-06-21 05:03:00) [46]Ну, в общем я понял. Задача не имеет простого решения. А делать сложные я небуду.
Fay (2004-06-21 04:53:00) [47]Всё, уже вижу. 8)
А значения локальных переменных процедур "кешировать" не надо?!!!
Какой-то...
Удачи.
Fay (2004-06-21 04:50:00) [48]
> Пример - сама Виндос, которая кэширует запись/чтение на
> диск, причём так, что для пользователя это можно сказать
> незаметно.
А что тебе говорит мозг, кеширует "Виндос" 300 метров, или нет?
Снова спрошу
При повторно запуске ЧЕГО надо избежать минутной задержки?!
Алекс А (2004-06-21 04:48:00) [49]
> Fay (21.06.04 04:36) [16]
> При повторном запуске чего?
Программы конечно.
Алекс А (2004-06-21 04:46:00) [50]
procedure TSharedStream.LoadFromFile(const FileName: string);
var
Stream: TFileStream;
begin
Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
LoadFromStream(Stream)
finally
Stream.Free
end
end;
Это же мой код! Вон я в первом постинге его написал. Просто один в один. Стырили. :)
В общем как я понял SharedStream позволяет просто грузить массив по частям, причём чего загружено, а чего нет, думать самому. Слишком неудобно это как-то.
Fay (2004-06-21 04:36:00) [51]При повторном запуске чего?
Алекс А (2004-06-21 04:35:00) [52]
> Fay (21.06.04 03:59) [11]
> > и всю прочую рутину сама бы выполняла
>
> 1) Так не бывает 8)
Бывает, когда кто нибудь напишет. Пример - сама Виндос, которая кэширует запись/чтение на диск, причём так, что для пользователя это можно сказать незаметно.
> 2) А зачем тогда ты?!
Чтобы данные анализировать.
Алекс А (2004-06-21 04:20:00) [53]
> ЮЮ © (21.06.04 04:05) [12]
> А на компе памяти сколько? Не приводит ли такое считывание
> "в память" к записи в своп?
512 Мб. Не приводит. Но и не кэшируется. При повторном запуске приходится опять ждать минуту.
> Fay (21.06.04 03:53) [9]
> CreateFileMapping ку?
Нашёл статью об этом : http://www.delphiworld.narod.ru/base/file_of_sop.html
Про него написано :
* TSharedStream работает правильно только с файлом подкачки,
с обычным файлом проще и надежнее работать TFileStream'ом.
* Для тех кто знаком с File Mapping Functions'ами :
Класс TSharedStream не может использоваться для синхронизации(разделения)
данных среди различных процессов(программ/приложений). [пояснения в конструкторе]
* Класс TSharedStream можно рассматривать как альтернативу
временным файлам (т.е. как замену TFileStream).
Преимущество :
а. Данные никто не сможет просмотреть.
б. Страница, зарезервированная под данные, автомотически освобождается
после уничтожения создавшего ее TSharedStream'а.
* Класс TSharedStream можно рассматривать как альтернативу
TMemoryStream.
Преимущество :
а. Не надо опасаться нехватки памяти при большом объеме записываемых данных.
[случай когда физически нехватает места на диске здесь не рассматривается].
И что это даёт ? Я и так не опасаюсь нехватки места на диске ...
Fay (2004-06-21 04:15:00) [54]... ёжик задумался...
8)
ЮЮ (2004-06-21 04:05:00) [55]А на компе памяти сколько? Не приводит ли такое считывание "в память" к записи в своп?
Fay (2004-06-21 03:59:00) [56]В Delphi традиционно нет средств, работающик "как нибудь".
Всё работает совершенно конкретным образом.
> и всю прочую рутину сама бы выполняла
1) Так не бывает 8)
2) А зачем тогда ты?!
Fay (2004-06-21 03:55:00) [57]Не, точно не ку 8)
Fay (2004-06-21 03:53:00) [58]CreateFileMappingку?
Алекс А (2004-06-21 03:50:00) [59]
> Fay (21.06.04 03:43) [7]
> Можно зрузить мегабайтными () блоками и хранить массив с
> инфой о том, какие блоки уже загружены. А грузит лучше через
> CreateFile/SetFilePointer/ReadFile.
Боюсь, что слишком гиморойно будет.
А нет ли какого нибудь менеджера памяти, который бы это сам делал? Чтобы просто проассоциировать массив с файлом на диске, и Дэльфи как нибудь сама бы это подгружала по мере необходимости, буферизировала бы, и всю прочую рутину сама бы выполняла?
Fay (2004-06-21 03:43:00) [60]Можно зрузить мегабайтными () блоками и хранить массив с инфой о том, какие блоки уже загружены. А грузит лучше через CreateFile/SetFilePointer/ReadFile.