Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Быстрый вывод большого количества инфы в МЕМО


Автор: sabbatazh 17.7.2008, 14:37
Здравствуйте, Все!!!!

Я зашел в тупик...  smile .... читаю блоками из нескольких фалов, большого размера, определнного размера значения и вывожу в несколько компонентов МЕМО... - это происходит медленно .... переделал это под потоки - запускаю несколько потоков (class(TThread)), процесс вывода ускорился... но не существенно... 
Если есть возможность быстрого вывода инфы в МЕМО, то пожскажите плиз.... !!!!!!!!!!!
Может использовать TFileStream?! Покажите пример как использовать механизм функции BlockRead в TFileStream.... 

Заранее Благодарю!!!! smile 

Автор: aleksh 17.7.2008, 14:51
основная проблема со скоростью, зачастую, связана с визуальным компонентом, в данном случае прорисовка в мемо, отсюда предложение: может данные выводить в мемо не сразу после прочтения; хранить их в какой-то временной структуре (вроде кэша будет), и выводить периодическу структуру. то есть: прочел раз пять-шесть-больше -- вывел в мемо, кэш очистил...
а считывать надо именно блоками?

Автор: sabbatazh 17.7.2008, 17:43
ДА... вот именно шо тока блоками....

читаю через буфер (массив)....

Автор: dumb 22.7.2008, 18:49
попробуй воспользоваться советом, приведенным в конце http://forum.vingrad.ru/index.php?showtopic=193936&view=findpost&p=1398402.

Автор: Jek1975 1.3.2009, 18:04
Кто-нибудь может объяснить почему первый вариант кода выполняется почти в 10 рез медленнее, чем второй вариант?
Что нужно сделать чтобы первый вариант выполнялся так же быстро?

Код

var i:integer;
....
Memo1.Lines.BeginUpdate;
 for i:=0 to 100000 do
    Memo1.Lines.Add('Тест A. Строка №'+IntToStr(i));
 Memo1.Lines.EndUpdate;


Код

var L:tStringList; i:integer;
....
L:=tStringList.Create;

 for i:=0 to 100000 do
    L.Add('Тест B. Строка №'+IntToStr(i));

 L.SaveToFile('test.txt');
 L.Free;

 Memo1.Lines.BeginUpdate;
 Memo1.Lines.LoadFromFile('test.txt');
 Memo1.Lines.EndUpdate;

Автор: Christoph 1.3.2009, 18:13
Код

Memo1.Lines.BeginUpdate;
  for i := 1 to 5000 do
    Memo1.Lines.Add('abcd');
Memo1.Lines.EndUpdate;


»  without BeginUpdate/EndUpdate: 25 seconds...
»  with BeginUpdate/EndUpdate: 0.6 seconds!

http://www.festra.com/eng/tip-beginupdate.htm

в 1 примере никак не увеличишь скорость, ну можешь себе комп быстрее поставить smile

во втором примере BeginUpdate EndUpdate смысловой нагрузки не несет, так как что с этими методами что без них (BeginUpdate EndUpdate), мемо перерисуется 1 раз

Автор: Jek1975 1.3.2009, 18:27
Christoph

Если не заметно что BeginUpdate и EndUpdate у меня в коде ЕСТЬ, то запусти пример из вложения, и убедись, что не в них дело.

Автор: Christoph 1.3.2009, 18:47
вот убери в 1 коде BeginUpdate и посмотри сколько будет выполняться, и во втором убери BeginUpdate, если во втором разницы не почувствуешь, а вот в первом почуствуешь  smile 

Автор: Jek1975 1.3.2009, 19:04
Christoph, извини, чувак, у меня конечно есть некоторый запас терпения, но я НЕ спрашиваю как замедлить код, я спрашиваю, что нужно сделать, чтобы оба куска выполнялись одинаково быстро. Если не знаешь, то лучше, пожалуйста, не отвечай.

Последний раз показываю что BeginUpdate и EndUpdate в моем примере НИКАК не способствуют тому, чтобы время выполнения обоих кусков сравнялось!!!

                     Memo [сек]    StringList+Memo [сек]
с Updates       10,910                  1,284
без Updates   58,990                  1,346


Автор: MetalFan 1.3.2009, 19:35
Jek1975, так, спокойнее! чувак, не гни пальцы, а то сломаешь.
по теме: при LoadFromXXX BeginUpdate/EndUpdate вызывать нет необходимости, ибо они и так вызываются в TStirngs.LoadFromStream.
для ускорения загрузки в Мемо имеет смысл не добавлять по одной строчке, а грузить их "скопом" из потока.

Автор: Jek1975 1.3.2009, 20:15
MetalFan, получется что не существует никаких других способов ускорения, кроме LoadFrom...?
Тогда как это реализовать в программе наиболее правильным способом?

Если я правильно понял, то в своем объекте, из которого я могу получить список строк (которые можно создать только в цикле) нужно делать не так:
Код

tMyDataStorage = class(TObject)
 public
    procedure GetText (var Lines:tStrings);
 end;

а так:
Код

tMyDataStorage = class(TObject)
 public
   GetText:TStream;
 end;

И вызывать не, MyDataStorage.GetText (Memo1.Lines) 
,а Memo1.Lines.LoadFromStream (MyDataStorage.GetText);

Я Вас правильно понял?

Извините, если понял что-то не так ...я только использовал готовые потоки (файлы), свои не создавал. Поэтому и спрашиваю насчёт правильности их использования.

Автор: MetalFan 1.3.2009, 21:05
на самом деле можно провести эксперимент...
нет, я был не прав. судя по коду TStrings(TMemoStrings) что загрузка из TStream, что из другого TStrings один фиг в итоге вызывает TStrings.Insert для КАЖДОЙ строки. следует заметить, что и Assign и LoadFromStream делают сами внутри себя BeginUpdate/EndUpdate.
а что, если попробовать загрузить текст в мемо через TMemo.Lines.Text := ... или TControl.SetTextBuf...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)