Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 27.02.2011, 23:40
Сорокин_Роман Сорокин_Роман вне форума
Прохожий
 
Регистрация: 29.11.2010
Сообщения: 34
Репутация: 10
По умолчанию Оптимизация ListView

Есть функция, на вход которой подаётся
Код:
var sbItems: arTStrings; var cpItems: arString
Код:
type arTStrings = array of TStrings;
type arString = array of string;
В sbItems содержатся SubItem'ы будущих Item'ов. В cpItems содержатся Caption'ы будущих Item'ов.

Вот сама функция:
Код:
  with FormMain.ListGame do
  begin
    Clear;
    count := Length(gameList) - 1;
    if count > FormMain.spnMaxCount.value then
      count := FormMain.spnMaxCount.value;
    if count > 0 then
      FormLoadScreen.Showload;
    {На вышеприведенные мусор не обращайте внимание. Это просто подсчёт
     количества Item'ов и вычистку ListView'а}
    for i := 0 to count do
    begin
      FormLoadScreen.SetCount(i, count); //Это чисто техническая. Не обращайте внимания
      li := Items.Add; //Добавляем пустой Item
      li.Data := gameList[i]; //Приписываем ему объект
      li.Caption := cpItems[i]; //Приписываем ему Caption
      li.ImageIndex := -1; //Приписываем пустой значок
      li.SubItems := sbItems[i]; //Приписываем SubItem'ы
      li.SubItemImages[9] := 2; //Одному из SubItem'ов приписываем значок
    end;
  end;
  FormLoadScreen.HideLoad;

Данный метод работает очень медленно. Уже поздно, поэтому зависимость Time(count) пока проводить не буду. Но при count = 13500 заполняет 18 секунд на не самом медленном процессоре! Есть возможность оптимизировать?
Ответить с цитированием
  #2  
Старый 28.02.2011, 01:20
Asinkrit Asinkrit вне форума
Местный
 
Регистрация: 29.10.2009
Сообщения: 446
Репутация: 271
По умолчанию

Должно помочь, но грузить в лист 14 тысяч значений, на самом деле не вариант, лучше добавить какой-нибудь фильтр, и выводить по фильтру не более 500.
Код:
  ...
  Items.BeginUpdate;
    Clear;
    count := Length(gameList) - 1;
    if count > FormMain.spnMaxCount.value then
      count := FormMain.spnMaxCount.value;
    if count > 0 then
      FormLoadScreen.Showload;
    for i := 0 to count do
    begin
      FormLoadScreen.SetCount(i, count); //Это чисто техническая. Не обращайте внимания
      li := Items.Add; //Добавляем пустой Item
      li.Data := gameList[i]; //Приписываем ему объект
      li.Caption := cpItems[i]; //Приписываем ему Caption
      li.ImageIndex := -1; //Приписываем пустой значок
      li.SubItems := sbItems[i]; //Приписываем SubItem'ы
      li.SubItemImages[9] := 2; //Одному из SubItem'ов приписываем значок
    end;
  Items.EndUpdate;
  ...

Последний раз редактировалось Asinkrit, 28.02.2011 в 01:23.
Ответить с цитированием
  #3  
Старый 28.02.2011, 02:28
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Код:
Try
  ListView1.Items.BeginUpdate;
  // Далее добавляем итемы
Finally
  ListView1.Items.EndUpdate;
End;

Должно сильно помочь.
Далее только оптимизация по загрузке данных, но она уже не сильно поможет. Тогда лучше переходить на БД. Там есть режим, когда загружается в один момент только то, что отображается, а потом по мере надобности подгружается. Хотя и с ListView можно пойти темже путем - грузить в отдельном потоке, вернув управление пользователю.
Ответить с цитированием
  #4  
Старый 28.02.2011, 10:47
Сорокин_Роман Сорокин_Роман вне форума
Прохожий
 
Регистрация: 29.11.2010
Сообщения: 34
Репутация: 10
По умолчанию

На первый взгляд не особо помогло. Вечером проведу точное тестирование зависимости time(count) для двух случаев.

ЗЫ: дело в том, что в ListView лист Item'ов представлен типом "TListItem", но и сами Item'ы представлены в точно таком же (по названию) типе "TListItem", но по содержанию - в другом. При объявлении переменной типа TListItem:
Код:
var
  listItem: TListItem
объявляется именно Item, поэтому нет возможности хранить лист Item'ов отдельно, а потом подключать к ListView'у.
Вопрос: как это сделать?

ЗЫ2: а при добавлении Item'а напрямую походу происходит не только его добавление, а ещё какие-то манипуляции с уже имеющимися Item'ами: если вывести в ProgressBar прогресс добавления Item'ов, то можно заметить, что на поздних этапах прогресс существенно замедляется. Опять же, точную зависимость выведу вечерам.

Последний раз редактировалось Сорокин_Роман, 28.02.2011 в 10:52.
Ответить с цитированием
  #5  
Старый 28.02.2011, 13:00
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Цитата:
Сообщение от Сорокин_Роман
дело в том, что в ListView лист Item'ов представлен типом "TListItem", но и сами Item'ы представлены в точно таком же (по названию) типе "TListItem", но по содержанию - в другом.
ну, ну, ну...
у TListView свойство Items имеет тип TListItems, тогда как элемент Items[х] (Items.Item[х]) имеет тип TListItem.
__________________
Пишу программы за еду.
__________________

Последний раз редактировалось NumLock, 28.02.2011 в 13:02.
Ответить с цитированием
  #6  
Старый 28.02.2011, 17:16
Сорокин_Роман Сорокин_Роман вне форума
Прохожий
 
Регистрация: 29.11.2010
Сообщения: 34
Репутация: 10
По умолчанию

Это называется, за компьютером пересидел.
Ответить с цитированием
  #7  
Старый 28.02.2011, 21:02
Сорокин_Роман Сорокин_Роман вне форума
Прохожий
 
Регистрация: 29.11.2010
Сообщения: 34
Репутация: 10
По умолчанию

Провёл исследование зависимости Time(count). Исследования проводил для count = 500, 1000, 1500...13000. Интересные результаты:
Код:
time   count
 500	 0.40
 1000	 0.78
 1500	 0.140
 2000	 0.215
 2500	 0.305
 3000	 0.402
 3500	 0.514
 4000	 0.642
 4500	 0.780
 5000	 0.936
 5500	 1.129
 6000	 1.372
 6500	 1.603
 7000	 1.925
 7500	 2.327
 8000	 2.742
 8500	 3.254
 9000	 3.787
 9500	 4.333
 10000	 4.933
 10500	 5.578
 11000	 6.193
 11500	 6.867
 12000	 7.581
 12500	 8.324
 13000	 9.101

Зависимость явно не линейная (а по идее таковой должна быть). Регрессионный анализ для квадратичного уравнения даёт:
Код:
(7.1373504*10^(-5))*x^2-0.2598452*x+386.81

На малых значениях count совпадения нет вообще. Но при count > 8000 совпадение почти полное! При count = 22000 получаем time = 29215, что расходится с экспериментом на 576 мс, при count = 18000 расхождение составляет 56 мс!

Главный вывод: все предыдущие Item'ы влияют на время при добавлении текущего Item'а. Как бороться?

Последний раз редактировалось Сорокин_Роман, 28.02.2011 в 21:08.
Ответить с цитированием
Ответ


Delphi Sources

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

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 23:05.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025