Seite 1 von 1

QDataStream vs. ifstream

Verfasst: 3. Juli 2006 11:23
von GwarDrazul
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

Verfasst: 3. Juli 2006 11:39
von patrik08
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;
}

Verfasst: 4. Juli 2006 10:42
von GwarDrazul
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

Verfasst: 4. Juli 2006 11:15
von macman
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ß.

Verfasst: 5. Juli 2006 12:20
von GwarDrazul
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)