Dateien einlesen | Das muss doch schneller gehen
-
Hallo,
ich lese aus 108 Dateien 1.192.555 Datensätzen ein und das dauert sage und schreibe 6,5 Minuten. Wenn ich diese Zeit immer warten muss bevor ich irgendeine kleine Änderung am Programm testen kann, dann bin ich ja alt bevor das Programm fertig ist. Andererseits müssen die Daten auch alle gleichzeitig im Programm sein.Wie kann man das ganze schneller machen?
Bisher lese ich die Daten so ein:
BOOL CHSIDepotmanagerDlg::load_stock_data() { //// // Vorbereitung des CProgress-Fensters m_progress_dialog.init(0,m_stockCtrl.GetItemCount()); m_progress_dialog.show(); m_progress_dialog.setText("Laden der historischen Kursdaten ..."); //// // Einlesen der Kursdaten CString stock_symbol, filename, fullpath, strLesePuffer, error, header, substring; CStdioFile DateiLesen; int stock_index; int rows_read=0; for(stock_index=0; stock_index<m_stockCtrl.GetItemCount(); stock_index++) { stock_symbol = m_stockCtrl.GetItemText(stock_index,0); filename = stock_symbol; filename.Replace(".","_"); filename += ".csv"; fullpath = path_stock_data + "\\" + filename; header = "Date,Open,High,Low,Close,Volume,Adj. Close*"; int pos, last_pos, length, satz_ident; bool abbruch; if (DateiLesen.Open(fullpath, CFile::modeRead)) { while(DateiLesen.ReadString(strLesePuffer)) { strLesePuffer.TrimLeft(); strLesePuffer.TrimRight(); if(strLesePuffer.Find(header,0)==-1) { pos = 0; last_pos = 0; satz_ident=0; abbruch = false; while(true) { pos = strLesePuffer.Find(",",last_pos); if(pos==-1){ length = strLesePuffer.GetLength()-last_pos; abbruch = true; }else length = pos-last_pos; substring = strLesePuffer.Mid(last_pos,length); if(satz_ident==0){ stockDB[stock_index].InsertItem(stockDB[stock_index].GetItemCount(),substring); rows_read++; }else stockDB[stock_index].SetItemText(stockDB[stock_index].GetItemCount()-1,satz_ident,substring); last_pos = pos+1; satz_ident += 1; if(abbruch) break; } } Sleep(1); } }else { error.Format("Es ist eine Fehler beim Lesen der Datei %s aufgetreten.",filename); MessageBox(error,"Lesefehler",MB_ICONINFORMATION); } m_progress_dialog.m_ctlProgress.SetPos(stock_index+1); } //// // Beenden des CProgress-Fensters m_progress_dialog.hide(); // //// CString a; a.Format("%i",rows_read); MessageBox(a); return true; }
-
du könntest 'memory mapped files' benutzen. guckst du: http://msdn2.microsoft.com/en-gb/library/aa366537.aspx
damit kannst du die files über pointer ansprechen (als hättest du sie in den speicher geladen).
wenn das nichts hilft, hast du woanders eine bremse drin.

-
Und wie lange dauert davon das Einfügen in den ListView?
-
MKF schrieb:
Und wie lange dauert davon das Einfügen in den ListView?
Ich würde auch eher vermuten, dass es daran liegt.
Lass mal die Einfügeoperationen weg und prüf, wie lange es dann dauert.
Wenn es an den Controls liegt, benutz ein virtuelles Listcontrol (LVS_OWNERDATA).
-
Wenn ich die Daten in die CListCtrl schreibe dauert es ca. 8 Minuten, wenn die Daten nicht eingefügt werden dauert es ca. 6 Minuten. Der Zeitunterschied ist also nicht zu vernachlässigen aber das virtuelle Listenelement gefällt mir nicht.
Ich habe gerade darüber nachgedacht statt der CListCtrl's nen struct und nen Array zu nehmen, in das dann die Daten kommen. Würde das schneller gehen?
Ich komme gerade irgendwie nicht weiter.
Michael
-
- Nimm das "Sleep(1)" raus - was soll das da drin?
- Lies grössere Stücke ein, oder verwende eine File API die selbst puffert (z.B. ifstream oder einfach fopen)
-
Das Sleep(1) ist da, damit die CPU Auslastung nicht bei 100% liegt. Die Funktion wird von einem Thread ausgeführt, das hätte ich vielleicht dazu sagen sollen.
Größere Stücke einlesen geht mit der aktuellen Variante nicht, weil die Datei zur Zeit zeilenweise eingelesen wird. Ich werd auch mal eine der von dir genannten Varianten testen.
Einen schönen Fortschritt konnte ich mit Multithreading erzielen. Statt ~8 Min. braucht das Programm jetzt nur noch ~1 Min..
Grüße,
Michael
-
mhecker schrieb:
Das Sleep(1) ist da, damit die CPU Auslastung nicht bei 100% liegt. Die Funktion wird von einem Thread ausgeführt, das hätte ich vielleicht dazu sagen sollen.
Größere Stücke einlesen geht mit der aktuellen Variante nicht, weil die Datei zur Zeit zeilenweise eingelesen wird. Ich werd auch mal eine der von dir genannten Varianten testen.
Einen schönen Fortschritt konnte ich mit Multithreading erzielen. Statt ~8 Min. braucht das Programm jetzt nur noch ~1 Min..
Grüße,
MichaelBlubb?
Dir ist schon klar dass Sleep(1) u.U. 15msec oder mehr dauert, ja?
Und dass das bei 1 Mio Zeilen u.U. recht lange werden kann?
Und dass es keinen Sinn macht das Sleep da zu haben - stell den Thread einfach auf normale Priorität, und wenn dir das zu sehr bremst einfach auf "below normal".
-
Okay, mein Fehler!
Sleep ist raus.