View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0001837SAS.Планета[All Projects] Багpublic27-02-2013 13:1302-07-2013 06:53
ReporterGarl 
Assigned Tozed 
PrioritynormalSeveritymajorReproducibilityalways
StatusresolvedResolutionfixed 
PlatformWindowsOS7OS VersionProfessional
Product Version.Nightly 
Target Version131111Fixed in Version131111 
Summary0001837: Out of memory при поиске по большому .txt файлу
Descriptionuserdata\txt\allCountries.txt 982Мб
при поиске долго ищет, и вылетает в ошибку.
Additional Informationесли подскажите как лечить - попробую вылечить самостоятельно
Tagsпоиск
Attached Files? file icon SASPlanet.Debug.elf [^] (68,205 bytes) 27-02-2013 13:13
? file icon u_MappedFile.pas [^] (2,730 bytes) 27-02-2013 14:15

- Relationships

-  Notes
(0010653)
vdemidov (manager)
27-02-2013 13:49

Не считывать файл полностью в память, а читать постепенно прямо из файла
(0010654)
zed (manager)
27-02-2013 13:57

Просто нужно читать файл построчно. Там такой формат, что одна строка - один населённый пункт. Очень удобно.

// Open existing text file and show first line
procedure ReadTxt;
var
  F: Textfile;
  str: string;
begin
  AssignFile(f, 'c:\ek.txt'); {Assigns the Filename}
  Reset(f); {Opens the file for reading}
  Readln(f, str);
  ShowMessage('1. line of textfile:' + str);
  Closefile(f); {Closes file F}
end;
(0010655)
Garl (manager)
27-02-2013 14:00

построчно не проиграем в производительности?
и в файле конец строки задан одним символом $0A
(0010656)
zed (manager)
27-02-2013 14:09

Сильно не проиграешь. А можешь и наоборот выиграть, если искомая комбинация будет найдена где-нибудь в начале файла.

Ещё, как вариант, можно открывать файл как MemoryMapped - тогда винда прозрачно оптимизирует считывание данных из файла. Но придётся работать с PChar и вручную искать конец строки.
(0010657)
Garl (manager)
27-02-2013 14:12

ну мы и так вручную ищем КонецСтроки
есть пример работы с MemoryMapped?
(0010658)
zed (manager)
27-02-2013 14:22
edited on: 27-02-2013 14:22

Прикрепил юнит.

Использовать можно как-то так:

VFile := TMappedFile.Create('c:\test.txt');
VData := PByte(VFile.Content);
for I := 0 to VFile.Size - 1 do begin
  if VData^ = $0A then begin
  // найден конец строки
  end;
  Inc(VData);
end;
VFile.Free;

(0010760)
vasketsov (manager)
02-03-2013 09:16
edited on: 02-03-2013 09:17

Есть подозрение, что можно читать блоками скажем по 4k. Всё равно системный кэш будет поднимать с диска такими (или аналогичными в соответствии с настройками оси и железа) блоками. Ну и в этом случае ищется либо начало искомого текста либо конец строки (если нашлось начало текста - ищем после него конец строки, при необходимости подгружая следующий блок, потом проверяем что нашли искомое, нет - перепрыгиваем на длину искомой строки и продолжаем), и вся эта котовасия покуда или не найдётся или файл не кончится. Хотя может там сложнее формат, и так не получится.
А посрочно конечно медленно, да и делает RTL то же самое примерно, поднимает с диска в кэш и ищет конец строки, выплёвывает их покуда есть чего, не зная ни о формате, ни о том, насколько можно упростить проверку, чего нашли.
В любом случае чиать весь гиговый файл враз конечно неправильно.

(0010761)
vdemidov (manager)
02-03-2013 09:31

>В любом случае чиать весь гиговый файл враз конечно неправильно.
Как и мапить его целиком в адресное пространство.
Нужно сделать нормальное чтение, например с буферизацией при помощи MapViewOfFile по кускам.
(0010762)
zed (manager)
02-03-2013 10:37
edited on: 02-03-2013 10:49

Мне почему-то казалось, что винда должна была сама мапить файл по-странично (теми же кусками по 4k), с периодическим сбрасыванием ненужных страниц. Но почему-то всё не так (:

Похоже, что периодический вызов VirtualUnlock мог бы решить проблему:
http://stackoverflow.com/questions/1880714/createfilemapping-mapviewoffile-how-to-avoid-holding-up-the-system-memory/1882478

(0010764)
vasketsov (manager)
02-03-2013 11:04

Не понимаю как VirtualUnlock может помочь в этом, это вообще "из другой оперы". Когда мапится файл, создаётся объект типа "секция" (ZwCreateSection+ZwMapViewOfSection), до Mm от него как до Луны в известной позе.

>с периодическим сбрасыванием ненужных страниц
А откуда известно, что страницы больше не нужны?

зы. Я б ограничился обычным файловым чтением в статический буфер, файл открывается для последовательного чтения, буфер дописывается в string, и далее поиск, ещё поиск, ещё поиск, не нашли - ещё читаем буферок, и т.п... зачем тут файл-то маппить в память?
(0010765)
zed (manager)
02-03-2013 11:10

>А откуда известно, что страницы больше не нужны?
Никто в них в данный момент времени не пишет/не читает = не нужны.

>зачем тут файл-то маппить в память?
Предполагалось, что не будет жрать память и не нужно с буферками напрягаться.
(0010767)
vasketsov (manager)
02-03-2013 11:22

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

>и не нужно с буферками напрягаться
А всё равно нужно будет напрягаться. Доступ-то последовательный. Соответственно если граница буфера попадает посередине искомого слова - "напряжение" и возникает, чтение следующего, стыковка, поиск и т.п.

К сожалению я не знаю простой нормальный системный способ открыть файл для последовательного доступа на чтение и тянуть его построчно, ограничив размер "окошка" и не долбясь с буферами, даже на Native NT API.

- Users who viewed this issue
User List Anonymous (1689x)
Total Views 1689
Last View 26-09-2020 13:11

- Issue History
Date Modified Username Field Change
27-02-2013 13:13 Garl New Issue
27-02-2013 13:13 Garl File Added: SASPlanet.Debug.elf
27-02-2013 13:14 Garl Tag Attached: поиск
27-02-2013 13:49 vdemidov Note Added: 0010653
27-02-2013 13:57 zed Note Added: 0010654
27-02-2013 14:00 Garl Note Added: 0010655
27-02-2013 14:09 zed Note Added: 0010656
27-02-2013 14:12 Garl Note Added: 0010657
27-02-2013 14:15 zed File Added: u_MappedFile.pas
27-02-2013 14:22 zed Note Added: 0010658
27-02-2013 14:22 zed Note Edited: 0010658 View Revisions
28-02-2013 04:45 Garl Assigned To => Garl
28-02-2013 04:45 Garl Status new => resolved
28-02-2013 04:45 Garl Resolution open => fixed
28-02-2013 04:45 Garl Fixed in Version => 131111
28-02-2013 04:45 Garl Target Version => 131111
02-03-2013 08:33 vdemidov Status resolved => confirmed
02-03-2013 08:33 vdemidov Resolution fixed => reopened
02-03-2013 08:33 vdemidov Fixed in Version 131111 =>
02-03-2013 09:16 vasketsov Note Added: 0010760
02-03-2013 09:17 vasketsov Note Edited: 0010760 View Revisions
02-03-2013 09:31 vdemidov Note Added: 0010761
02-03-2013 10:37 zed Note Added: 0010762
02-03-2013 10:49 zed Note Edited: 0010762 View Revisions
02-03-2013 11:04 vasketsov Note Added: 0010764
02-03-2013 11:10 zed Note Added: 0010765
02-03-2013 11:22 vasketsov Note Added: 0010767
06-03-2013 06:20 vdemidov Status confirmed => resolved
06-03-2013 06:20 vdemidov Fixed in Version => 131111
06-03-2013 06:20 vdemidov Resolution reopened => fixed
06-03-2013 06:20 vdemidov Assigned To Garl => zed
02-07-2013 06:53 vdemidov Product Version 131111 => .Nightly



Copyright © 2007 - 2020 SAS.Planet Team