If you use a Lazarus component like a ListBox, Memo, TreeList, ListView,... and you add or modify a lot of items (lines, nodes,...), the component's performance becomes very slow. This is due to the fact that after each change, it is redrawn on the screen.
Thus, modifying 10000 items of a ListBox causes 10000 redraws, and that takes from several seconds to several minutes, depending on the computer's speed and the complexity of the process. Imagine how slow it can become if the process involves inserting, deleting, modifying and swapping many thousands of items.
But you can speed up things enormously with the following tip:
Call BeginUpdate before making the changes to the items. When all changes are complete, call EndUpdate to show the changes on screen. BeginUpdate and EndUpdate prevent excessive redraws and speed up processing time when items are added, deleted, or inserted.
Here's a simple source code example for using this technique with a ListBox:
ListBox1.Items.BeginUpdate;
for i := 1 to 10000 do
ListBox1.Items.Add('abcd');
ListBox1.Items.EndUpdate;
To give you an idea of the improvement, we timed the code above (your PC may be faster or slower):
» without the BeginUpdate/EndUpdate lines: 4.3 seconds...
» with BeginUpdate/EndUpdate: 0.1 seconds, that's 43 times faster!
Here's a source code example for using this technique with a Memo:
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!
Ускорение работы с listbox, combobox, memo ...
Модератор: Модераторы
Ускорение работы с listbox, combobox, memo ...
Кстати очень полезная вещь!!!
- debi12345
- долгожитель
- Сообщения: 5761
- Зарегистрирован: 10.05.2006 23:41:15
- Откуда: Ташкент (Узбекистан)
This is due to the fact that after each change, it is redrawn on the screen.
Да, для не БД-виджетов этот запрет синхронной перерисовки очень полезен, потому что узнать без помощи самого программиста, когда начинается и когда закачивается заполнение списка - невозможно (в отличие от БД-виджетов, для которых для этих дел автоматически вызываются DisableControls/EnableControls связанного датасета).
- debi12345
- долгожитель
- Сообщения: 5761
- Зарегистрирован: 10.05.2006 23:41:15
- Откуда: Ташкент (Узбекистан)
Вы что-то не так меряли. Или со сверхтяжелым тулкитом вроде GTK2.
У меня прорисовка данных со связкой полей :
занимает 1.5 секунды (причем на стареньком Р3-700)
100.000 рисуются 15 секунд при первом открытии списка, потом - практически мгновенно.
Загрузка миллиона записей без связки полей :
заняла 7 секунд, 100.000 и менее - практически мгновенно.
У меня прорисовка данных со связкой полей :
Код: Выделить всё
procedure tmainfo.created(const sender: TObject);
var
i: integer;
s: msestring;
begin
for i:= 1 to 10000 do begin
s:= 'Item '+ inttostr(i);
lbuf.addrow([i],[s],[]);
end;
end;
занимает 1.5 секунды (причем на стареньком Р3-700)
100.000 рисуются 15 секунд при первом открытии списка, потом - практически мгновенно.
Загрузка миллиона записей без связки полей :
Код: Выделить всё
begin
for i:= 1 to 1000000 do begin
arr:= opentodynarraym( [ 'Item ' + inttostr(i)] );
tenumedit1.addrow(arr);
end;
end;
заняла 7 секунд, 100.000 и менее - практически мгновенно.
- Maxx_ir
- новенький
- Сообщения: 12
- Зарегистрирован: 24.02.2008 19:52:00
- Откуда: Тольятти
- Контактная информация:
Вы попробуйте именно TListBox
>>
ListBox1.Items.BeginUpdate;
for i := 0 to 10000 do
begin
ListBox1.Items.Add(IntToStr(i));
end;
ListBox1.Items.EndUpdate;
>>
Да нет там никакого GTK2!
Проверял Mandriva2005 - GTK,
Debiah - DSL 3.4.1 - это чудо вообще не требовательно к ресурсам полный дистр 50 mb -это и есть целевая ось для embed системы, не проверил на списках > 1000 строк а тут такие грабли
>>
ListBox1.Items.BeginUpdate;
for i := 0 to 10000 do
begin
ListBox1.Items.Add(IntToStr(i));
end;
ListBox1.Items.EndUpdate;
>>
Да нет там никакого GTK2!
Проверял Mandriva2005 - GTK,
Debiah - DSL 3.4.1 - это чудо вообще не требовательно к ресурсам полный дистр 50 mb -это и есть целевая ось для embed системы, не проверил на списках > 1000 строк а тут такие грабли
- debi12345
- долгожитель
- Сообщения: 5761
- Зарегистрирован: 10.05.2006 23:41:15
- Откуда: Ташкент (Узбекистан)
Attid писал(а):в трекер.
а пользователь точно нормально сможет выбрать из списка в 10000 ? =)
Как ни странно - без проблем (мне это тоже стало интересно). Даже с миллионом записей:) К тому же список подстраивается под ручной ввод в текстовой зоне.
Главное - чтобы не тормозило при каждом раскрытии списка.
- Maxx_ir
- новенький
- Сообщения: 12
- Зарегистрирован: 24.02.2008 19:52:00
- Откуда: Тольятти
- Контактная информация:
alexs писал(а):Ибо нефиг такие списки делать.
Это понятно нефиг - нафиг
А что здесь в топике написано ?
Here's a simple source code example for using this technique with a ListBox:
ListBox1.Items.BeginUpdate;
for i := 1 to 10000 do
ListBox1.Items.Add('abcd');
ListBox1.Items.EndUpdate;
To give you an idea of the improvement, we timed the code above (your PC may be faster or slower):
» without the BeginUpdate/EndUpdate lines: 4.3 seconds...
» with BeginUpdate/EndUpdate: 0.1 seconds, that's 43 times faster!
» without BeginUpdate/EndUpdate: 25 seconds...
» with BeginUpdate/EndUpdate: 0.6 seconds
Брехня не работает
