2016-04-13 8 views
0

У меня есть программа, которая в контуре обрабатывает двоичные данные из файла.Tuning QDataStream

Код очертание является следующее:

QFile fileIn ("the_file"); 
fileIn.open(QIODevice::ReadOnly); 

Файл имеет сочетание двоичных и текстовых данных. Содержимое файла считываются с помощью QDataStream:

QDataStream stream(&fileIn); 
stream.setByteOrder(QDataStream::LittleEndian); 
stream.setVersion(QDataStream::Qt_5_0); 

Я могу прочитать данные из QDataStream в различные типы данных. например

QString the_value; // String 
stream >> the_value; 
qint32 the_num; 
stream >> the_numm; 

Ницца и легко. В целом я прочитал байты данных файла байтом, пока не ударил определенные значения, которые представляют собой разделители, например. 0x68 0x48. В этот момент я затем следую за следующими парами байтов, которые расскажут, какой тип данных следующий (floats, Strings, ints и т. Д.) И извлеките, если необходимо.

Таким образом, данные orocessed (контур), как:

while (! stream.atEnd()) 
{ 
    qint8 byte1 = getInt8(stream); 
    qint8 byte2 = getInt8(stream); 
    if (byte1 == 0x68 && byte2 == 0x48) 
    { 
     qint8 byte3 = getInt8(stream); 
     qint8 byte4 = getInt8(stream); 
     if (byte3 == 0x1 && byte4 == 0x7) 
     { 
      do_this(stream); 
     } 
     else if (byte3 == 0x2 && byte4 == 0x8) 
     { 
      do_that(stream); 
     } 
    } 
} 

Некоторые из этих внедренных данных могут быть сжаты, поэтому мы используем

long dSize = 1024; 
QByteArray dS = qUncompress(stream.device()->read(dSize)); 

QBuffer buffer; 
buffer.setData(dS); 

if (!buffer.open(QBuffer::ReadOnly)) { 
    qFatal("Buffer could not be opened. Something is very wrong!"); 
} 

QDataStream stream2(&buffer); 
stream2.setByteOrder(QDataStream::LittleEndian); 
stream2.setVersion(QDataStream::Qt_5_0); 

Удобство QDataStream позволяет легко читать данные с точки зрения сопоставления конкретным типам, но также и для удобной обработки endianess, но, похоже, это за счет скорости. Проблемы усугубляются тем фактом, что обработка является рекурсивной - считываемые данные сами могут содержать встроенные данные файла, которые должны быть прочитаны и обработаны таким же образом.

Есть ли альтернатива, которая выполняется быстрее, и поэтому, если, как тогда обращаться с Endianess одинаково?

+1

«Но это, кажется, за счет скорости». Кажется, какая-то функциональность стоит за счет скорости? Кажется, что один? Может быть, имеет смысл исследовать, какой код отвечает за то, что он медленный? Это приводит к недопущению преждевременной оптимизации, что плохо. Можете ли вы сделать профилирование? – AlexanderVX

ответ

1

Вашего код выглядит прямо вперед .. рекурсии не должна быть шоу пробки ...

У вас есть много строк? Тысячи?

stream >> stringвыделяет память, используя new Что действительно медленное. И требуется , который будет освобожден вручную впоследствии. Обратитесь к Qt Docs за методом operator>>(char *&s). Это используется при чтении в QStrings.

То же самое верно для readBytes(char *&s, uint &l), которое можно назвать внутренне замедляющим все!

Сам QString также выделяет память (в два раза больше, чем использует 16-битную кодировку), что замедляется дальше.

Если вы часто используете одну из этих функций, подумайте над переписыванием частей кода для прямого чтения в предварительно выделенный буфер с использованием readRawData(char *s, int len) перед дальнейшей обработкой.

В целом, если вам нужна высокая производительность QDataStream, вполне может быть показательным стопором.

+0

Спасибо Аррон - некоторые полезные подсказки. – TenG