Форум: "Основная";
Текущий архив: 2004.07.11;
Скачать: [xml.tar.bz2];
ВнизКак лучше работать с 300-мегабайтным массивом ? Найти похожие ветки
← →
wicked © (2004-06-22 11:02) [40]упс... а куда ушло форматирование?... :(
← →
jack128 © (2004-06-22 11:32) [41]
> Конечно на произвольном доступе немного отстает, но за
> счет опережающего чтения во многих случаях быстрее. Но это
> не главная характеристика
главная характеристика в ДАННОМ случае - скорость произвольного доступа. По крайней мере так автор сказал.
> Digitman © (22.06.04 08:57)
> а нашута велосипед изобретать ?
Скажите, вы всю информацию в своих форматах в БД храните?
И насчет мапирования:
Может я чего то не понимаю, но AFAIK при использовании мапирования в ОЗУ нечего не загружается. Поэтому скорость доступа никак не изменяет, это лишь вопрос удобства, не больше. А в форуме несколько раз проскакивало, что таким образом можно ускорить доступ к файлу. Может кто из сведущих прояснит ситуацию?
← →
Digitman © (2004-06-22 11:41) [42]
> jack128 © (22.06.04 11:32) [41]
структурированную инф-цию такого объема, разумеется, в БД храню.. а почему бы и нет ? если есть готовый достаточно производительный механизм быстрого доступа к элементам НД ?
← →
wicked © (2004-06-22 11:42) [43]
> А в форуме несколько раз проскакивало, что таким образом
> можно ускорить доступ к файлу. Может кто из сведущих прояснит
> ситуацию?
может... 400 мб файл с собственным форматом данных загружается за полсекунды-секунду... это вместе с предобработкой (создание таблиц в памяти)...
← →
jack128 © (2004-06-22 11:52) [44]а есть предположения почему MemoryStream.CopyFrom(FileStream, FileStream.Size) происходит минуту?
← →
wicked © (2004-06-22 11:59) [45]
> а есть предположения почему MemoryStream.CopyFrom(FileStream,
> FileStream.Size) происходит минуту?
есть...
1. CopyFrom работает на уровне TStream и копирует содержимое блоками по 60 кб (примерно, точное число в исходниках)...
2. TMemoryStream при необходимости увеличить место под данные просто перевыделяет память через GlobalAlloc/GlobalFree... при этом, чем больше памяти было выделено до операции, тем больше времени займет само перераспределение...
т. о. CopyFrom на каждой итерации буде вызывать дорогое (и стающее всё более дорогим) перераспределение памяти...
самый простой метод лечения - MemoryStream.Size := FileStream.Size до копирования...
← →
jack128 © (2004-06-22 12:18) [46]
> CopyFrom на каждой итерации буде вызывать дорогое (и стающее
> всё более дорогим) перераспределение памяти...
> самый простой метод лечения - MemoryStream.Size := FileStream.Size
> до копирования...
в СopyFrom так и сделано.. можно узнать, а как ты проверял, что у тя файл в ОЗУ загрузился?
у мя такой вот тестик с 300 метровым файлом 1,5 минуты длился..procedure TForm1.Button1Click(Sender: TObject);
var
p: Pointer;
hFile: THandle;
fSize: Cardinal;
t, Dummy: Cardinal;
begin
if not od.Execute then Exit;
t := GetTickCount;
hFile := CreateFile(PChar(od.Filename), GENERIC_READ, 0, nil,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if hFile = INVALID_HANDLE_VALUE then
RaiseLastWin32Error;
try
fSize := SetFilePointer(hFile, 0, nil, FILE_END);
GetMem(p, fSize);
try
SetFilePointer(hFile, 0, nil, FILE_BEGIN);
if not ReadFile(hFile, p^, fSize, dummy, nil) then
RaiseLastWin32Error;
finally
FreeMem(p);
end;
finally
CloseHandle(hFile);
end;
Caption := IntToStr(GetTickCount - t);
end;
← →
wicked © (2004-06-22 12:28) [47]
> можно узнать, а как ты проверял, что у тя файл в ОЗУ загрузился?
то есть?... если выполнилась ф-ция загрузки, значит он там... :)
> у мя такой вот тестик с 300 метровым файлом 1,5 минуты длился..
очень аппаратно-зависимый тест - на его результаты влияют:
1. скорость дисковой подсистемы...
2. ФС, на которой файл живёт...
3. степень фрагментированности диска...
4. режимы работы харда (дма и т.д.)...
это всё факторы, влияние которых должно быть неощутимо... но это не так... :(
← →
jack128 © (2004-06-22 12:36) [48]
> то есть?... если выполнилась ф-ция загрузки, значит он там...
> :)
Под ОЗУ я подрузамеваю модули памяти, а не память виндоуз. Память в Windows физически может распалогаться и на жестком диске и вообще на чем угодно, но эти насители имеют весьма низкую скорость чтения/записи в отличии от ОЗУ. Поэтому я и говорю, что мапирование файла скорость не может увеличить - этот аппаратная проблема. Мапирование лишь отображает файл на ВАП, физически файл никуда не копируется..
← →
wicked © (2004-06-22 12:46) [49]мапирование файла ускоряет доступ к нему не потому, что оно какое то волшебное, а потому, что оно фактически ничего не делает кроме указания менеджеру памяти, что под эти адреса этого процесса "подложен" этот файл...
загрузка данных происходит только тогда, когда аппликация обращается непосредственно к этим адресам... именно поэтому произвольный доступ к небольшим участкам (до 4 - 16 кб последовательно - 1 - 4 страницы памяти) происходит почти мгновенно - коммитятся и наполняются данными необходимые страницы...
если же после создания memory mapped файла попытаться последовательно прочесть в цикле все данные, то по скорости этот метод будет равен простому чтению файла с помощью ReadFile...
← →
jack128 © (2004-06-22 12:56) [50]
> именно поэтому произвольный доступ к небольшим участкам
> (до 4 - 16 кб последовательно - 1 - 4 страницы памяти) происходит
> почти мгновенно - коммитятся и наполняются данными необходимые
> страницы...
а что, если я эти небольшие участки памяти буду читать с помощью ReadFile будет медленнее? Но почему?
← →
wicked © (2004-06-22 13:00) [51]
> а что, если я эти небольшие участки памяти буду читать с
> помощью ReadFile будет медленнее? Но почему?
не медленнее... геморойней - выделить память, seek, прочесть, опять seek, записать...
а так - отмерил offset скока надо и читай-пиши...
← →
wicked © (2004-06-22 13:02) [52]плюс не стоит забывать, что windows сама кеширует запись в мапленные участки памяти... и при закрытии нужно делать FlushViewOfFile...
← →
jack128 © (2004-06-22 13:03) [53]Итак вывод - MapFile - только для удобства!!! Скорость работы никак не измениться.
← →
wicked © (2004-06-22 13:06) [54]не совсем...
тут количество переходит в качество - удобство работы предполагает и наталкивает способы, которые никогда бы не пришли в голову, если бы работа с файлом велась через ReadFile...
← →
jack128 © (2004-06-22 13:14) [55]Да? Нужно попробовать... Хотя я так подумал, меня бы это натолкнуло на такие решения, которые бы замедлили работу с файламии :-)
Все таки подсознательно сидит - раз память, значит быстрый доступ..
← →
wicked © (2004-06-22 13:18) [56]тогда см [39] - писалось для себя...
хотя, если найдутся багофичи, то хотелось бы о них знать... ;)
← →
MacroDenS © (2004-06-22 14:37) [57]
// Что чаще загружается - никогда заранее не известно.
да при первом запуске конечно же неизвестно, а потом после первой загрузки становится известно, особенно если это учитывать.
К примеру можно же создать файл с такой структурой:
ID LoadingNum
1 159
4 87
4567125 14
и так далее...
← →
Алекс А (2004-06-23 01:21) [58]
> Almaz © (22.06.04 04:55) [33]
Спасибо за пример! Попробовал так сделать.
Только у меня неPChar
, аBase1 : array[0..SizeB1-1] of Longword;
Поменял наBase1 : PLongWord;
, так на первом же вызове (CountBit(Base1[i1]
) пишет ошибку[Error] Unit1.pas(615): Array type required
. Что здесь не так ?
← →
Роман (2004-06-23 09:32) [59]FileMapping отличается в корне от ReadFile: ответственность за кеширование в первом случае лежит на драйверах устройства (это может быть не только диск, но и, например, видеокарта AGP!) и осуществляется посредством прямого копирования данных в RAM посредством DMA, во втором же случае - используется буферизированная файловая система Windows. FileMapping всегда быстрее ReadFile т.к. специально разрабатывался для этих целей. Читайте Рихтера, господа.
← →
Игорь Шевченко © (2004-06-23 10:30) [60]
> ответственность за кеширование в первом случае лежит на
> драйверах устройства
Ответственность за кеширование лежит на менеджере кэша, как ни странно
← →
Игорь Шевченко © (2004-06-23 10:32) [61]
> FileMapping ...
> осуществляется посредством прямого копирования данных в
> RAM посредством DMA
Бред
← →
Anatoly Podgoretsky © (2004-06-23 11:14) [62]Роман (23.06.04 09:32) [59]
Здесь правильно только про Рихтера.
← →
Palladin © (2004-06-24 00:00) [63]:)))
← →
Almaz © (2004-06-24 00:43) [64]
> Алекс А (23.06.04 01:21) [58]
>
> > Almaz © (22.06.04 04:55) [33]
>
> Спасибо за пример! Попробовал так сделать.
> Только у меня не PChar, а Base1 : array[0..SizeB1-1] of
> Longword;
>
> Поменял на Base1 : PLongWord;, так на первом же вызове (
> CountBit(Base1[i1] ) пишет ошибку [Error] Unit1.pas(615):
> Array type required. Что здесь не так ?
Дело в том, что PChar рассматривается Object Pascal как указатель на массив, поэтому запись MyArray[I] - правомерна. А PLongWord - это просто указатель на переменную типа LongWord. Поэтому, для использования массива LongWord его надо описать:type
TLongwordArray = array [0..MaxInt div 16 - 1] of Longword;
PLongwordArray = ^TLongwordArray;
...
MyArray: PLongwordArray;
...
А в вашем случае:PLongword = ^Longword;
- это не массив, поэтому компилятор "ругается".
Удачи.
← →
default © (2004-06-24 00:58) [65]Anatoly Podgoretsky © (23.06.04 11:14) [62]
да, читал я про MMF у Рихтера ничего подобного там не было
← →
Алекс А (2004-06-24 01:57) [66]
> Almaz © (24.06.04 00:43) [64]
Заработало ! :) Грузит моментом. Торможения даже незаметно. Или может просто задачи подходящей не попалось ещё ? Но всё равно очень здорово. Спасибо !
Всем рекомендую.
А с насколько большими файлами можно так работать ? Можно ли с файлами большими High(LongWord) или хотя бы с большими High(Integer) ?
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2004.07.11;
Скачать: [xml.tar.bz2];
Память: 0.59 MB
Время: 0.035 c