Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: FAQ - MFC ::  CListCtrl - Erfahrungsaustausch virtuelle Tabellen mit CListCtrl     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
koreson
Mitglied

Benutzerprofil
Anmeldungsdatum: 01.02.2005
Beiträge: 47
Beitrag koreson Mitglied 02:02:53 20.03.2005   Titel:   CListCtrl - Erfahrungsaustausch virtuelle Tabellen mit CListCtrl            Zitieren

Hi,

war irgendwie überrascht als ich nach der Implementation einer virtuellen Tabelle mit CListCtrl folgendes feststellte:

Basis war eine Tabelle mit Wertpapierkursdaten auf einem lokalen MySQL-Server.
300.000 Zeilen mit 8 Spalten, alles varchar. 31,2 MB auf der Platte.
Dann 2 Dialoge gemacht. Ein Dialog ruft die Tabelle konventionell auf, der andere Dialog als virtuelle Tabelle mit OnLvnGetdispinfo.
Folgende Zeitmessungen bis zum vollständigen Aufbau und Darstellung der Tabelle gemessen:

Zeilen Konventionell Virtuell
5000 10,5 sec 5,8 sec (freu)
10000 21,1 sec 12 sec (freu weiter)
30000 32,1 sec 38 sec (Schock !!!)
100000 83,3 sec kein Bock mehr zu warten, Prozessmanager

Nach jedem Dialog natürlich das Programm neu gestartet, um unfaire Speicherhinterlassenschaften auszuschliessen.
Das ganze ist reproduzierbar und liegt weder an der Tabelle noch am Rechner.
Habs auf einem anderen Client probiert.
Der Speicherbedarf zur Ausführzeit steigt bei beiden Verfahren in etwa gleich schnell an und ist auch nach Darstellung der Tabelle ziemlich gleich.

Wie kommt denn das? Laut MSDN wird vollmundig der virtuelle Ansatz empfohlen, wenns um grosse Tabellen geht.
Kennt das Phänomen jemand ???
Im übrigen frag ich mich jetzt schon, wie ich solche Tabellenmonster in angemessener Zeit auf den Schirm bekomme ohne gleich ein limit einzubauen wie es bei vielen Datenbank-frontends der Fall ist.


Gruss
koreson


Zuletzt bearbeitet von estartu am 11:00:17 16.01.2006, insgesamt 1-mal bearbeitet
Werbeunterbrechung
peterchen
Autor

Benutzerprofil
Anmeldungsdatum: 16.09.2003
Beiträge: 2251
Beitrag peterchen Autor 10:00:02 20.03.2005   Titel:              Zitieren

Irgendwas machst du falsch :)
eiver virtuelles ListControl fragt normalerweise nur die sichtbaren Einträge ab, geht also rasend schnell. Das "Aufbauen" beschränkt sich also auf das Setzen der endgültigen Länge und di Abfrage+Darstellung der sichtbarein Einträge.

Checkliste:

- LVS_OWNERDATA in der Resource bzw. beim Erzeugen des Controls
- einmal LVM_SETITEMCOUNT, um die Anzahl der elemente zu setzen
- LVN_GETDISPINFO: testet item.mask, welche Daten angefordert werden

_________________
ph
volkard
Moderator

Benutzerprofil
Anmeldungsdatum: 06.04.2000
Beiträge: 24356
Beitrag volkard Moderator 10:16:59 20.03.2005   Titel:   Re: Erfahrungsaustasuch virtuelle Tabellen mit CListCtrl            Zitieren

koreson schrieb:
Zeilen Konventionell Virtuell
5000 10,5 sec 5,8 sec (freu)
10000 21,1 sec 12 sec (freu weiter)
30000 32,1 sec 38 sec (Schock !!!)
100000 83,3 sec kein Bock mehr zu warten, Prozessmanager

wird da mit bubble-sort oder insertion-sort was sortiert?

_________________
http://www.venganza.info/
plonk fürs Forum v1.02
koreson
Mitglied

Benutzerprofil
Anmeldungsdatum: 01.02.2005
Beiträge: 47
Beitrag koreson Mitglied 15:03:20 20.03.2005   Titel:              Zitieren

Hi,

Hab den Übeltäter gestern Nacht noch lokalisiert:

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
CString element;   
    while ((mRecord = mysql_fetch_row(mTabelle)) != NULL)
    {
        m_database.push_back(vector<CString>());

        for (int j=0;  j < max_cols;  j++)
        {
        element = mRecord[j];
        m_database.back().push_back(element);
        }
    i++;
    }
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
CString element;
while ((mRecord = mysql_fetch_row(mTabelle)) != NULL)
{
m_database.push_back(vector<CString>());

for (int j=0; j < max_cols; j++)
{
element = mRecord[j];
m_database.back().push_back(element);
}
i++;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
CString element;   
    while ((mRecord = mysql_fetch_row(mTabelle)) != NULL)
    {
        m_database.push_back(vector<CString>());

        for (int j=0;  j < max_cols;  j++)
        {
        element = mRecord[j];
        m_database.back().push_back(element);
        }
    i++;
    }


Das Kopieren der Daten in diesen 2-dim vector ist alles andere als performant.
Wenn ich das weglasse, gehts rasend schnell, allerdings stürzt das Progi dann ab, weil ich nicht weiss, wie man nur die sichtbaren records aus der mTabelle-Struktur rausholt.

D.h ich weiss nicht, wie ich das Ergebnis mTabelle in der der OnLvnGetdispinfo-Methode verarbeiten kann ohne while(mysql_fetch_row...) zu verwenden, die zZt. noch so aussieht und auch funktioniert:
C/C++ Code:
void CTestDlg::OnLvnGetdispinfoList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
LV_ITEM* pItem= &(pDispInfo)->item;
lstrcpyn(pItem->pszText, m_database[pItem->iItem][pItem->iSubItem], pItem->cchTextMax);
*pResult = 0;
}
C/C++ Code:
void CTestDlg::OnLvnGetdispinfoList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
LV_ITEM* pItem= &(pDispInfo)->item;
lstrcpyn(pItem->pszText, m_database[pItem->iItem][pItem->iSubItem], pItem->cchTextMax);
*pResult = 0;
}
C/C++ Code:
void CTestDlg::OnLvnGetdispinfoList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
LV_ITEM* pItem= &(pDispInfo)->item;
lstrcpyn(pItem->pszText, m_database[pItem->iItem][pItem->iSubItem], pItem->cchTextMax);
*pResult = 0;
}

Wenn da jemand vielleicht ne Idee hat, wie's ohne das Kopiere in den vector funzt, könnte mir das den Sonntag nachmittag retten :)
Wäre fast geneigt, für ne Lösung was zu bieten, ist nämlich für mein Projekt ziemlich wichtig.

gruss
koreson
koreson
Mitglied

Benutzerprofil
Anmeldungsdatum: 01.02.2005
Beiträge: 47
Beitrag koreson Mitglied 15:33:00 20.03.2005   Titel:              Zitieren

So, Sontag nachmittag gerettet. Hier die Lösung:

Ohne das Zwischenkopieren in den vector.

C/C++ Code:
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
void CTestDlg::OnLvnGetdispinfoList1(NMHDR *pNMHDR, LRESULT *pResult)
    {
    LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
         LV_ITEM* pItem= &(pDispInfo)->item;
       mysql_data_seek (mTabelle, pItem->iItem);      
       mRecord = mysql_fetch_row(mTabelle);
       lstrcpyn(pItem->pszText, mRecord[pItem->iSubItem], pItem->cchTextMax);
    *pResult = 0;
    }
C/C++ Code:
1
2
3
4
5
6
7
8
9
void CTestDlg::OnLvnGetdispinfoList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
LV_ITEM* pItem= &(pDispInfo)->item;
mysql_data_seek (mTabelle, pItem->iItem);
mRecord = mysql_fetch_row(mTabelle);
lstrcpyn(pItem->pszText, mRecord[pItem->iSubItem], pItem->cchTextMax);
*pResult = 0;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
void CTestDlg::OnLvnGetdispinfoList1(NMHDR *pNMHDR, LRESULT *pResult)
    {
    LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
         LV_ITEM* pItem= &(pDispInfo)->item;
       mysql_data_seek (mTabelle, pItem->iItem);      
       mRecord = mysql_fetch_row(mTabelle);
       lstrcpyn(pItem->pszText, mRecord[pItem->iSubItem], pItem->cchTextMax);
    *pResult = 0;
    }


Zeigt die 300.000 in ca 3 sec an. Scrollt recht schnell und stürtzt nicht ab.
:D :D :D
Wäre das nicht was für die FAQ?

Gruss
koreson
C/C++ Forum :: FAQ - MFC ::  CListCtrl - Erfahrungsaustausch virtuelle Tabellen mit CListCtrl   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können keine Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum nicht antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.