Alles rund um die Programmierung mit Qt
GwarDrazul
Beiträge: 23 Registriert: 5. Juni 2006 18:56
Beitrag
von GwarDrazul » 3. Juli 2006 11:23
Hallo zusammen,
Ich habe festgestellt, dass ein QDataStream zum Einlesen einer 16MB Datei ca. 10 min. braucht während der c++ - ifstream nur 8.5 Sec benötigt.
Mache ich hier etwas falsch oder ist das tatsächlich so? Im Prinzip würde ich lieber auf die Qt-Klassen als auf die c++ Klassen zurückgreifen (wg. garantierter Plattformunabängigkeit).
Hier der relevante Code:
Mit QDataStream:
Code: Alles auswählen
QFile file (filename);
if (!file.open(QIODevice::ReadOnly)) return;
QDataStream in(&file);
in.setByteOrder(QDataStream::LittleEndian);
// Calculate size:
const unsigned int DATASIZE = m_width*m_height*m_depth;
// Allocate data
quint8 *data = new quint8 [DATASIZE];
for (unsigned int i = 0; i < DATASIZE; ++i)
{
// read data
in >> data[i];
// Alternativ auch:
// in.readRawData(reinterpret_cast<char *>(&data[i]),1);
// gleich schlechtes zeitliches Resultat
}
Mit ifstream
Code: Alles auswählen
filename.replace(QRegExp("\\"),"\\\\");
std::string s = filename.toStdString();
const char* fn = s.data();
std::ifstream quelle(fn, std::ifstream::in | std::ifstream::binary);
if (!quelle)
{
QMessageBox::critical(0, QObject::tr("Error"), QObject::tr("File could not be opened"), QMessageBox::Ok, QMessageBox::NoButton);
return;
}
// Calculate size:
const unsigned int DATASIZE = m_width*m_height*m_depth;
// Allocate data
qint8 *data = new qint8 [DATASIZE];
for (unsigned int i = 0; i < DATASIZE; ++i)
{
quelle.read(reinterpret_cast<char *>(&data[i]),1);
}
// ******* Closing Source File
quelle.close();
Gruß,
Eric
patrik08
Beiträge: 746 Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg
Beitrag
von patrik08 » 3. Juli 2006 11:39
Warum QDataStream wenn es auch ohne geht?
auf dem mac habe ich eine 3Mb sql file geladen und updaten in etwa 5 sekunden...
Code: Alles auswählen
/* return file contenets as qstring */
QString Sqlitedb::utf8_file_get_contents( QString filename )
{
QString inside = "";
QFile file(filename);
if (file.exists()) {
if (file.open(QFile::ReadOnly | QFile::Text)) {
inside = QString::fromUtf8(file.readAll());
file.close();
}
}
return inside;
}
GwarDrazul
Beiträge: 23 Registriert: 5. Juni 2006 18:56
Beitrag
von GwarDrazul » 4. Juli 2006 10:42
Hi,
vielen Dank für die Antwort.
Ich habe jetzt sogar heraus gefunden,dass C-Funktionen noch schneller sind.
Code: Alles auswählen
filename.replace(QRegExp("\\"),"\\\\");
std::string s = filename.toStdString();
const char* fn = s.data();
int fd = open(fn, O_RDONLY);
if (fd == -1)
{
// fehler
perror("File could not be opened");
return -1;
}
int laenge = lseek(fd,0,SEEK_END);
quint8* t_data = (quint8*) mmap(0,laenge,PROT_READ,MAP_SHARED,fd,0);
Das ist wirklich blitzschnell (16 MB < 1 sec - über Netzlaufwerk!). Wenn das plattformunabhängig funktioniert werde ich wohl das verwenden da ich es oft mit sehr großen Datensätzen zu tun bekommen werde. Ansonsten probiere ich Deine Lösung noch mal.
Vielen Dank,
Eric
macman
Beiträge: 1738 Registriert: 15. Juni 2005 13:33
Wohnort: Gütersloh
Kontaktdaten:
Beitrag
von macman » 4. Juli 2006 11:15
Was habt ihr denn für ein Netzwerk? Bei 100MBit erreicht man bestenfalls gut 10 MByte/s. Plattformunabhängig ist es jedenfalls nicht, soviel ich weiß.
GwarDrazul
Beiträge: 23 Registriert: 5. Juni 2006 18:56
Beitrag
von GwarDrazul » 5. Juli 2006 12:20
Hi macman,
ehrlich gesagt kann ich Dir keine großen Auskünfte über das Netzwerk hier machen. Ich bin an der FH und habe nie nachgefragt...
Mit der Plattformunabhängigkeit hast Du (leider) Recht wie ich gerade festgestellt habe.
Gruß,
Eric
Nachtrag:
So geht es doch Plattformunabhängig:
http://cplus.kompf.de/artikel/memmap.html
(adaptiert, angepasst und getestet unter Lin und Win)