Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Lazarus, Free Pascal, CodeTyphon
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.11.2018, 07:15   #1
dima147
Пользователь
 
Регистрация: 15.09.2018
Сообщений: 10
Радость обработать большой текст

Доброго дня! Проблема с парсингом txt-лога размером больше 300Мб!!! Загружаю в stringlist из txt:

Код:
STR_ARR:= TStringList.Create;  //проинициализировали массив
try STR_ARR.LoadFromFile(w);  //Создаём массив строк из файла
except
end;
Лог состоит из строк которые проверяю на наличие слов и далее вывожу в synedit. При запуске гружу весь массив в synedit:

Код:
 SynEdit1.Lines.BeginUpdate;
   SynEdit1.clear;   //очмстка поля вывода
SynEdit1.Lines.Text := STR_ARR.Text;
   SynEdit1.Lines.EndUpdate;
Так вот - проблема: при создании массива строк из файла в 200Мб получаю память в 800Мб! Далее, при загрузке массива строк в synedit - память становится около 1700Мб!!!!
Изначально вся работа проги строится на стринглисте и синедите (там удобная подсветка слов по тексту).
Временно решил часть проблемы расширением памяти под приложение ключом {$SETPEFLAGS $0020}, но на x32 упираюсь по-любому в 300Мб лога, а нужен 1Гб! Кто что посоветует? Желательно с кодом решений т.к. работаю в lazarusе только 6 мес..
dima147 вне форума Ответить с цитированием
Старый 20.11.2018, 07:48   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

А зачем StringList? LoadFromFile есть и в SynEdit
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 20.11.2018, 12:51   #3
dima147
Пользователь
 
Регистрация: 15.09.2018
Сообщений: 10
По умолчанию

Задача - парсить весь лог и стринглист проще отрабатывает и быстрее..
Пробегаю по строкам-ищу например время записи(в виде цифр в начале каждой строки) и если надо - вывожу на синедит! А стринглист в памяти как исходный набор строк..

отловил основные причины роста памяти при загрузке и обработке:
- стринглист удваивает размер исходного файла;
- преобразование cp1251toutf8 ещё рост в 2 раза;
- гружу в синедит - +столько же, и того в 6-7 раз растёт размер памяти под файл!!!

Последний раз редактировалось Вадим Мошев; 21.11.2018 в 14:21.
dima147 вне форума Ответить с цитированием
Старый 20.11.2018, 13:20   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

стринглист не удваивает
обращение к STR_ARR.Text + столько же памяти, как и в самом массиве строк стринглиста.
преобразование cp1251toutf8 естесно еще столько + много чего, оно же мультибайтное
lines в синедит это тоже strings со всеми вытекающими
так что меняй логику )
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 20.11.2018 в 13:22.
Аватар вне форума Ответить с цитированием
Старый 20.11.2018, 13:30   #5
dima147
Пользователь
 
Регистрация: 15.09.2018
Сообщений: 10
По умолчанию

но без стринглиста при смене фильтров поиска придётся каждый раз грузить файл в память и обрабатывать его - хотелось остаться со стринглистом, а вот в синедит подгружать постранично фильтрованные строки? Но тогда я не знаю как организовать постраничный вывод и главное - как скроллбар организовать реальный на синедите - ведь в синедите будет не весь текст, а несколько страниц-навигация ползунка по тексту д.б. своя!
dima147 вне форума Ответить с цитированием
Старый 20.11.2018, 13:35   #6
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Можно смапить файл на память.
p51x на форуме Ответить с цитированием
Старый 20.11.2018, 13:45   #7
dima147
Пользователь
 
Регистрация: 15.09.2018
Сообщений: 10
По умолчанию

..в памяти и скорости получим выигрыш?..пример очень выручил бы!..т.е. грузить в память файл и оттуда обрабатывать с выводом строк в синедит? со разбором строк из памяти не будет гемороя?

..и всё-же если кто подкинет пример по организации скролла при поблочной загрузке в окне syneditа и маппинг большого файла - буду очень признателен!

Последний раз редактировалось Вадим Мошев; 21.11.2018 в 14:22.
dima147 вне форума Ответить с цитированием
Старый 21.11.2018, 08:49   #8
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Используйте ListBox1 в режиме виртуальной отрисовки.

Код:
var
  ListAns:TStringList;

В OnCreate 
ListBox1.style := lbVirtualOwnerDraw; // Используем свой метод отрисовки

По событию применения фильтра
ListBox1.Count := ListAns.Count; // Решаем проблему со скролингом


procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
var ListBox:TListBox;
Data:String;
Word1:String;
Word2:String;
begin
ListBox:=Control as TListBox;

if Index and 1=0 then
   ListBox.Canvas.Brush.Color:=TColor($F0D0D0)
   else
   ListBox.Canvas.Brush.Color:=clWhite;

ListBox.Canvas.FillRect(Rect);
Data:=ListAns[Index];
Word1:=Copy(Data,1, Pos(':', Data));
Word2:=Copy(Data,Pos(':', Data)+1, Length(Data)); 

ListBox.Canvas.Font.Color:=clPurple;
ListBox.Canvas.TextOut(Rect.Left,Rect.Top,Word1);
if Index and 1=0 then
   ListBox.Canvas.Font.Color:=clRed
   else
   ListBox.Canvas.Font.Color:=clGreen;
ListBox.Canvas.TextOut(ListBox.Canvas.PenPos.X, ListBox.Canvas.PenPos.Y,Word2);

if (odFocused in State) then
   ListBox.Canvas.DrawFocusRect(Rect);


end;


PS. Перезалил архив, теперь с pas файлом.
PPS. ListBox в лазарусе не доконца реализован.
Вложения
Тип файла: rar LogView.rar (170.0 Кб, 27 просмотров)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .

Последний раз редактировалось Pavia; 21.11.2018 в 14:28. Причина: Перезалил архив, теперь с pas файлом.
Pavia вне форума Ответить с цитированием
Старый 21.11.2018, 12:12   #9
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Pavia, у меня ваш проект на сгенерённом мной файлике (417 Мб) выдаёт Out of Memory

если Вам интересно - то файл генерил простенькой программкой:ProjectTest.rar
(работает долго, у меня генерация происходит около 12 минут)
Serge_Bliznykov вне форума Ответить с цитированием
Старый 21.11.2018, 13:17   #10
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Проглядел, что 1 ГБ.
Два варианта решения:
1) Тогда да от StringList отказаться. Добавить полосу прокрути как отдельный компонент, задать ей диапазоны от размера файла.
И при изменении полосы прокрутки загружать из файла необходимые данные.
2) Но я тут решил, что пора продвигать 64 бита в массы. Достаточно пересобрать программу.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Чем бы отобразить очень большой текст? i.polyakoff JavaScript, Ajax 5 15.04.2016 16:26
Как обработать текст в буфере перед вставкой в edit? Dux Общие вопросы Delphi 36 17.02.2016 13:11
Задан текст, состоящий из строк произвольной длины. Обработать текст, подсчитав количество строк и отсортировав их (Паскаль) Александр_Прог Помощь студентам 3 24.03.2014 14:37
SetWindowTextA, SendMessageA - не ставит большой текст ( PASHAsoska Общие вопросы Delphi 3 30.11.2012 15:51
write и большой текст Rebelition Паскаль, Turbo Pascal, PascalABC.NET 2 21.06.2011 21:41