CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Wczytanie dużej listy adresów do komponentu TListView

Wczytanie dużej listy adresów do komponentu TListView

dział ogólny

Wczytanie dużej listy adresów do komponentu TListView

Nowy postprzez Darek_C++ » niedziela, 6 lutego 2011, 15:17

Witam ponownie,
tym razem z zapytaniem o możliwość polepszenia wydajności wczytania danych do TListView.
Dane do ListView wczytuję w wątku następującym kodem:

KOD cpp:     UKRYJ  
void __fastcall WczytajZpliku::Execute()
{
        float Start = GetTickCount();
        Button->Enabled = false;
        TStringList * Lista = new TStringList();
        Lista->LoadFromFile(nazwaPliku);
        int jj = 1;

        for(int ii = 0; ii < Lista->Count; ii++)
        {
                String adres = Lista->Strings[ii].Trim();
                if(adres.IsEmpty()== false)
                {
                        TListItem * ElementListy=ListView1->Items->Add();
                        ElementListy->Caption = adres;
                        ElementListy->SubItems->Add("---");
                        ElementListy->SubItems->Add("---");
                        ++jj;
                        if((jj%100) == 0)
                        {
                                StatusBar1->Panels->Items[0]->Text="Lista zawiera "+IntToStr(jj)+" adresów";
                        }

                }
        }
        float End = GetTickCount();
        String sWCzasie = FloatToStr((End - Start) / 1000) + " s.";
        Button->Enabled = true;;

        delete Lista; Lista = NULL;
        int iDodanych = ListView1->Items->Count;
        StatusBar1->Panels->Items[0]->Text="Lista zawiera "+IntToStr(iDodanych)+" adresów. Czas wczytania: "+sWCzasie;
        StatusBar1->Panels->Items[1]->Text="---";
}
i wczytanie większych ilości dnach np 214542 adresów z pliku zajmuje bardzo dużo czasu 45 długich minut dla Release_Build :roll:

Pytanie brzmi czy idzie to przyspieszyć ?

----
Przy okazji... po kompilacji zwracana jest taka uwaga:
[C++ Warning] WatekWczytajZpliku.cpp(57): W8004 'Lista' is assigned a value that is never used
Której nie rozumiem przecież Lista jest używana w kodzie :)
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: Wczytanie dużej listy adresów do komponentu TListView

Nowy postprzez Cyfrowy Baron » niedziela, 6 lutego 2011, 16:59

Pierwsze opóźnienie powstaje przy wczytywaniu listy do obiektu TStringList, drugie w pętli przy przepisywaniu rekordów do ListView. Pierwsze opóźnienie można wyeliminować wczytując plik bezpośrednio do ListView, bez pośrednika, np.:

KOD cpp:     UKRYJ  
 ListView1->Items->Item[0]->SubItems->LoadFromFile("Nazwa pliku.roz");


To jednak na nic się nie przyda, gdyż wczytywane są kolumny nie wiersze. Wydaje się więc, że nie ma innej metody wczytania danych do ListView niż wiersz po wierszu w pętli, ale to oznacza, że nie ma czego przyspieszyć. Pewne przyspieszenie można by uzyskać rezygnując w pętli z warunku sprawdzającego, czy rekordy są puste, oraz z inkrementacji zmiennej jj. StatusBar też można wypełnić poza pętlą sprawdzając zamiast wartości zmiennej jj liczbę elementów na liście ListView.
KOD cpp:     UKRYJ  
 TStreamReader *sReader = new TStreamReader("c:\\test.txt");

 ListView1->Items->Clear();

 while(sReader->Peek() > -1)
 {
  String adres = sReader->ReadLine();

  TListItem * ElementListy = ListView1->Items->Add();
  ElementListy->Caption = adres;
  ElementListy->SubItems->Add("---");
  ElementListy->SubItems->Add("---");
 }

 sReader->Close();
 delete sReader;


To pewnie nie będzie wiele szybsze, jestem jednak ciekaw na ile szybsze.



Przy okazji... po kompilacji zwracana jest taka uwaga:

[C++ Warning] WatekWczytajZpliku.cpp(57): W8004 'Lista' is assigned a value that is never used


Której nie rozumiem przecież Lista jest używana w kodzie :)


Komunikat sugeruje, że obiekt Lista został utworzony, ale nigdzie nie jest używany. Takie komunikaty czasami się zdarzają, ale to ostrzeżenie nie błąd, więc go po prostu zignoruj.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4731
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 445
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Wczytanie dużej listy adresów do komponentu TListView

Nowy postprzez Darek_C++ » niedziela, 6 lutego 2011, 17:35

Nie mogę sprawdzić z powodu:

[C++ Error] WatekWczytajZpliku.cpp(34): E2451 Undefined symbol 'TStreamReader'


Widocznie Turbo C++ nie ma tej klasy :(
-----
Samo przejście w pętli z sprawdzaniem: if(adres.IsEmpty()== false)
w wyświetlaniem :
if((jj%100) == 0)
{
StatusBar1->Panels->Items[0]->Text="Lista zawiera "+IntToStr(jj)+" adresów";
}
Zajmuje tylko, 0.8 sekundy więc narzut czasowy na to jest pomijalni mały. W przeciwieństwie do wczytywanie do TListView :(
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: Wczytanie dużej listy adresów do komponentu TListView

Nowy postprzez polymorphism » poniedziałek, 7 lutego 2011, 11:08

W przypadku list view jedyny i efektywny sposób przyśpieszenia wczytywania danych, to przełączenie go w tryb wirtualny. W trybie tym list view nie trzyma danych, jedynie je wyświetla (w wątku z czytaniem plików CSV podałem przykład aplikacji czytającej do grida działającego w tym trybie. 1700000 wierszy w 10 sekund [z możliwością przyśpieszenia :)]).

Właściwość TListView::OwnerData przełącza list view w tryb wirtualny.

____
p.s. to są te same adresy z tematu o duplikatach?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2263
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 210
System operacyjny: Windows 8.1
Windows 10
Linux Mint 19
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Wczytanie dużej listy adresów do komponentu TListView

Nowy postprzez Cyfrowy Baron » poniedziałek, 7 lutego 2011, 11:37

Zajmuje tylko, 0.8 sekundy więc narzut czasowy na to jest pomijalni mały. W przeciwieństwie do wczytywanie do TListView :(


Jest to jednak zbędne, gdyż ListView zwraca ilość wierszy, więc dodatkowe wyliczanie rekordów jest niepotrzebne:

KOD cpp:     UKRYJ  
StatusBar1->Panels->Items[0]->Text="Lista zawiera " + IntToStr(ListView1->Items->Count) + " adresów";
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4731
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 445
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Wczytanie dużej listy adresów do komponentu TListView

Nowy postprzez Darek_C++ » poniedziałek, 7 lutego 2011, 12:41

Cyfrowy Baron napisał(a):Jest to jednak zbędne, gdyż ListView zwraca ilość wierszy, więc dodatkowe wyliczanie rekordów jest niepotrzebne:
To nie jest zbędne gdyż wizualizuje postęp wczytywania danych do ListView 'a :) Poza tym tam nic dodatkowo nie zlicza tylko wyświetla ile wczytano pod koniec odczytując właściwość:
int iDodanych = ListView1->Items->Count;

polymorphism napisał(a):W przypadku list view jedyny i efektywny sposób przyśpieszenia wczytywania danych, to przełączenie go w tryb wirtualny.
p.s. to są te same adresy z tematu o duplikatach?
Ustawiłem właściwość na ListView1->OwnerData = true;
I w przy tym ustawieniu 91230 lini z pliku wczytuje się w 39 sekund, dla porównania z OwnerData = false 521 sekund ;

Ale w tym trybie nie mam wizualnej prezentacji danych w ListView1 wiec co mi to daje - kontener dla danych ?

Tak, mowa o listach adresów www takich jak "z tematu o duplikatach"
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: Wczytanie dużej listy adresów do komponentu TListView

Nowy postprzez polymorphism » poniedziałek, 7 lutego 2011, 13:02

Ale w tym trybie nie mam wizualnej prezentacji danych w ListView1 wiec co mi to daje ?

Musisz zaimplementować obsługę odpowiednich zdarzeń, m.in. OnData. W tym trybie nie dodajesz elementów w taki sam sposób, jak robisz to w zwykłym trybie. Jedynie ustawiasz ilość elementów, a list view przy odświeżeniu widoku będzie Cię prosić o dane elementu, który ma zamiar narysować w kontrolce.

kontener dla danych ?

Wręcz przeciwnie. Jeszcze raz napiszę: w tym trybie kontrolka nie przechowuje elementów, jedynie je wyświetla. Zatem aplikacja w pełni zarządza danymi. Dzięki temu masz pełną kontrolę nad tym, jak i gdzie wczytujesz dane.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2263
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 210
System operacyjny: Windows 8.1
Windows 10
Linux Mint 19
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Wczytanie dużej listy adresów do komponentu TListView

Nowy postprzez Darek_C++ » poniedziałek, 7 lutego 2011, 14:32

Tylko jak to wszystko obsłużyć :zawiedziony: Nawet przesunięcie suwakiem wymaga osobnej obsługi danych.
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 1 gość

cron