调整 QDataStream
Posted
技术标签:
【中文标题】调整 QDataStream【英文标题】:Tuning QDataStream 【发布时间】:2016-04-13 23:08:38 【问题描述】:我有一个程序可以处理文件中的二进制数据。
代码大纲如下:
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。在这一点上,接下来是接下来的几个字节,它们告诉我接下来是什么类型的数据(浮点数、字符串、整数等)并酌情提取。
因此,数据被处理(大纲)如下:
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?
【问题讨论】:
“但似乎是以牺牲速度为代价的”。似乎某些功能是以牺牲速度为代价的?好像是那个?也许调查什么代码导致变慢是有意义的?这导致避免过早的优化,这是不好的。你能做一些分析吗? 【参考方案1】:您的代码看起来直截了当 .. 递归不应该成为阻碍...
你有很多字符串吗?几千?
stream >> string
分配内存使用new
真的很慢。之后需要手动释放。有关operator>>(char *&s)
方法的信息,请参阅Qt 文档。这在读入 QStrings 时使用。
readBytes(char *&s, uint &l)
也是如此,这可能在内部被称为减慢一切!
QString 本身也会分配内存(是它使用 16 位编码的两倍),这会进一步减慢速度。
如果您经常使用这些函数之一,请考虑重写代码部分,以便在进一步处理之前使用readRawData(char *s, int len)
直接读取到预分配的缓冲区。
总体而言,如果您需要高性能,QDataStream
本身可能就是最佳选择。
【讨论】:
以上是关于调整 QDataStream的主要内容,如果未能解决你的问题,请参考以下文章