Wolne działanie ListView

Wolne działanie ListView
AM
  • Rejestracja:około 19 lat
  • Ostatnio:3 miesiące
0

Cześć
Zacznę może od krótkiego opisu.

Aplikacja pobiera z tabeli około 1200 wpisów, to jest w zasadzie błyskawiczne, muszę to jednak wstawić do ListView i pogrupować. W sumie wszystkie rekordy (1200) będą w około 100 grupach. W prostej pętli For dopisuję kolejne rekordy i w razie czego uzupełniam grupy.

O ile samo dodanie rekordu nie jest problemem ListView.Items.Add(); podobnie jak uzupełnienie reszty danych to już dodanie grupy ListView.Groups.Add(); trwa wyraźnie za dłużej.

Zauważyłem, że czas ten rośnie im więcej jest grup. Przy około 30 grupach podanie kolejnej zajmuje około sekudnę. Można na to jakoś wpłynąć, przyspieszyć? Załadowanie do ListView 1200 rekordów trwa około minuty.

Z góry dzięki za sugestie.

edytowany 1x, ostatnio: flowCRANE
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
2

Może popróbuj z beginUpdate?


AM
  • Rejestracja:około 19 lat
  • Ostatnio:3 miesiące
0
Patryk27 napisał(a):

Może popróbuj z beginUpdate?

Pokombinowałem nieco i okazuje się, że wszystko działa szybciej jeżeli wpierw dodaję grupy, a później pozycje. Jeżeli grupy uzupełniam w trakcie dodawania pozycji to ListView strasznie spowalnia.
W tej chwili pomimo tego, że mam 2 pętle, pierwsza która tworzy grupy i druga która dopisuje pozycje do ListView, to działa to w zasadzie bez jakiegokolwiek opóźnienia...

Mam inne pytanie, tym razem związanie z wielkością czcionki użytej dla grup. Da się ją jakoś zmienić? Font obiektu ListView odnosi się tylko do pozycji. Grupy korzystają z czegoś innego. czego?

LA
OS a zatem VCL nie pozwala na to, możesz coś tam próbować ręcznie malować, ale nie od reki.
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 2 godziny
  • Lokalizacja:Tuchów
  • Postów:12171
2

@amidar: każda kontrolka posiadająca możliwość przechowywania mnóstwa itemów obsługuje metody BeginUpdate i EndUpdate. Służą one właśnie po to, aby poinformować kontrolkę o tym, że zawartość będzie zmieniania. Dzięki temu po każdorazowej zmianie zawartości (edycji, wstawieniu czy usunięciu pozycji), kontrolka nie odświeża swojej zawartości, a więc nie marnuje czasu na absolutnie zbędne operacje (np. przemalowanie interfejsu). Dlatego też zawsze używaj tych metod, jeśli tylko są dostępne. A dostępne są przede wszystkim w ListView, ListBox, ComboBox itd.

Czyli aby mocno przyspieszyć uzupełnianie kontrolki w dane, na samym początku wywołaj ListView.BeginUpdate, następnie zrób co masz zrobić (dodaj dane) i na samym końcu zawołaj ListView.EndUpdate.

Ale kosmicznej optymalizacji nie ma się co spodziewać po użyciu tych metod. Równie dobrze wąskie gardło może być gdzieś indziej (czyli w samym kodzie pobierającym dane lub je grupującym).

amidar napisał(a):

Mam inne pytanie, tym razem związanie z wielkością czcionki użytej dla grup. Da się ją jakoś zmienić? Font obiektu ListView odnosi się tylko do pozycji. Grupy korzystają z czegoś innego. czego?

VCL domyślnie korzysta ze stylu systemowego, tak więc aby móc malować pozycje inaczej, można skorzystać ze zdarzeń pozwalających własnoręcznie je malować. Jest ich kilka, więc jest w czym wybierać.

Poczytaj: Vcl.ComCtrls.TCustomListView.OnDrawItem.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 7x, ostatnio: flowCRANE
0

a sprawdzałeś może Virtual Treeview ?? Na pewno jest dużo szybszy niż Listview. Może akurat będzie Ci pasować.

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 2 godziny
  • Lokalizacja:Tuchów
  • Postów:12171
0

@amidar: jeśli chcesz wiedzieć coś więcej to pokaż kod przygotowujący zawartość kontrolki – być może on też wcale nie jest jakiś specjalnie optymalny i to powoduje problem wydajnościowy.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
WL
  • Rejestracja:ponad 21 lat
  • Ostatnio:12 dni
  • Postów:1083
0

Tam się nie za bardzo da to przyspieszyć, a @amidar już zrobił co mógł...
Pozostał Ci tylko tryb wirtualny, ale nie wiem czy jest sens.

NA Twoim miejscu zarzuciłbym całkowicie używanie TListView i zamienił go znakomitym Virtual-TreeView.
https://github.com/Virtual-TreeView/Virtual-TreeView/

Nie sugeruj się nazwą, ponieważ to jest wielokolumnowy TreeView, a więc może działać jak ListView.
Tylko lepiej, szybciej (pewnie 100x szybciej ; eee... to nieprawda, ponieważ "Virtual Treeview is extremely fast. Adding one million nodes takes only 700 milliseconds!*") i o naprawdę niebagatelnych możliwościach.
Tu więcej i łobrazki:
https://www.jam-software.com/virtual-treeview/features.shtml

edytowany 1x, ostatnio: wloochacz
AM
  • Rejestracja:około 19 lat
  • Ostatnio:3 miesiące
0

Wielkie dzięki za wszelkie uwagi. BeginUpdate i EndUpdate dołożyłem, ale po zmianie kolejności dodawania elementów różnica nie jest już jakaś specjalnie wielka. Całe przeładowanie trwa poniżej sekundy... jest to akceptowalne w porównaniu do poprzednich 60 sekund ;)

Za to zainteresował mnie Virtual TreeView. Wygląda obiecująco, być może podmienię go jeszcze teraz zanim zabrnę za daleko ;)

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 2 godziny
  • Lokalizacja:Tuchów
  • Postów:12171
1
amidar napisał(a):

Wielkie dzięki za wszelkie uwagi. BeginUpdate i EndUpdate dołożyłem, ale po zmianie kolejności dodawania elementów różnica nie jest już jakaś specjalnie wielka. Całe przeładowanie trwa poniżej sekundy... jest to akceptowalne w porównaniu do poprzednich 60 sekund ;)

Ha! Wiedziałem. :D

To też nie jest tak, że standardowe komponenty są jakoś szczególnie powolne (szczególnie szybkie też nie) – po prostu trzeba się nauczyć je obsługiwać. No i pozostaje jeszcze wydajność kodu pozyskującego dane, które dodajesz do kontrolki. W nim też może i można coś przyspieszyć, jednak bez kodu niczego więcej nie mogę napisać.

Żeby móc jeszcze bardziej zoptymalizować ten kod, trzeba by kuknąć do kodu tego komponentu i sprawdzić co wykonuje w danych przypadkach. W ten sposób można dojść do efektywnego (acz mniej czytelnego) rozwiązania. Choć pewnie nie ugra się tym zbyt wiele.

Za to zainteresował mnie Virtual TreeView. Wygląda obiecująco, być może podmienię go jeszcze teraz zanim zabrnę za daleko ;)

Na pewno warto poznać tę kontrolkę, bo daje niesamowite możliwości. Przykłady użytkowania możesz znaleźć w wyszukiwarce (przykładowe kody również). Standardowe kontrolki przydają się do prostych zastosowań, jednak do bardziej zaawansowanych i fikuśnych trzeba się gimnastykować i tu z pomocą przychodzi VirtualTreeView.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 3x, ostatnio: flowCRANE
robertz68
  • Rejestracja:ponad 18 lat
  • Ostatnio:około 13 godzin
  • Lokalizacja:Zielona Góra
0

hmm, a nie szybciej by było wczytać i pogrupować te elementy w jakiejś tablicy a dopiero później, gdy już są odpowiednio ułożone wrzucić do listview?

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.