【发布时间】:2015-08-18 21:50:55
【问题描述】:
在我的项目中,我编写了一个函数来解压缩 QString,该 QString 使用我在单独函数中编写的非常基本的压缩格式进行压缩。但是经过一些测试,我发现这个函数是导致严重减速的原因,因为它在巨大的 QString 上运行并被调用超过 2900 次。
我一直在尝试更改此功能以使其运行得更快。我曾尝试过使用 QStringRef,但效果不佳(我可能做错了)。 QByteArrays 和 QByteRefs 很难使用和检查值 (imo)。
我真的需要一些帮助来优化此功能,以便它运行FAST!尽可能快!我相信 .mid 的不断调用会减慢速度,但我只是不知道任何其他方式来读取/写入字节。
编辑:更好的问题,在减压功能方面我是否缺少一种常见的做法?我稍后在同一个程序中使用 zlib,它比我在下面编写的这个简单函数压缩得更快。这是为什么? zlib 有什么不同?
提前感谢您的宝贵时间。 :)
这是一个非常小的压缩 QString 的样子:
//Compressed
//This QString is just a hexadecimal representation of a QByteArray
//
QString com("010203ff0504ff0a05ff00ff01ff02ff0306);
还有,解压后相同的 QString 如下:
//Decompressed
QString decom("0102030404040404040505050505050505050505ffffffffffff06060606);
很抱歉,如果您不立即理解格式……那没关系。也许这会有所帮助:
-a byte with "ff" tells us we're about to decompress
-the byte after "ff" is the number of times to repeat the NEXT byte + 1
-UNLESS that number is 0, 1, or 2, then "ff" is the value to be repeated
Examples:
-"010203" decompressed is "010203"
-"ff0401" decompressed is "0101010101"
-"ff02" decompressed is "ffffff"
这是我写的解压函数:
int HexToIntS(QString num_hex) //converts the byte to a number
{
uint num_uint;
bool ok;
num_uint = num_hex.toUInt(&ok,16);
return (int)num_uint;
}
void Decompress(QString com, QString &decom)
{
QString c; //current byte
QString n; //new/next byte
int bytePos(0); //current position in QString
int byteRepeat; //number of times to repeat byte n
c = com.mid(bytePos, 2); //get first byte (01)
decom.clear(); //clear decom just in case it had values prior
do
{
bytePos = bytePos + 2; //move the current position to the next byte
if(c == "ff") //is decompression happening?
{
c = com.mid(bytePos, 2); //current byte is now the "next" byte
byteRepeat = HexToIntS(c); //c tells us how many times the NEXT byte needs to be repeated
if(byteRepeat <= 2) //if c's value is <= 2... then ff is the value
{
n = "ff"; //new byte is just ff
bytePos = bytePos + 2; //update the current position
}
else //if not, then c is the number of times the NEXT byte should be appended
{
n = com.mid(bytePos + 2, 2); //new byte is the NEXT byte
bytePos = bytePos + 4; //update the current position
}
for(int j = 0; j<=byteRepeat; j++)//append n the correct number of times
decom.append(n);
}
else //guess we're not decompressing, so just append c
decom.append(c);
c = com.mid(bytePos, 2); //get the new current byte
}while(bytePos < com.length()); //stop when all bytes were read
}
当前基于您的 cmets 优化的函数:(仅在调试模式下快 5%-10%)
void Decompress2(const QString com, QString &decom)
{
QStringRef c;
QString n;
int bytePos(0);
int byteRepeat;
c = com.midRef(bytePos, 2);
decom.clear();
do
{
bytePos = bytePos + 2;
if(c == "ff")
{
c = com.midRef(bytePos, 2);
byteRepeat = c.toString().toInt(0,16);
if(byteRepeat <= 2)
{
n = "ff";
bytePos = bytePos + 2;
}
else
{
n = com.mid(bytePos + 2, 2);
bytePos = bytePos + 4;
}
for(int j = 0; j<=byteRepeat; j++)
decom.append(n);
}
else
decom.append(c);
c = com.midRef(bytePos, 2);
}while(bytePos < com.length());
}
【问题讨论】:
-
您可以使用分析器来查看函数的哪个部分“消耗”了很多时间,并尝试使用运行速度更快的等效代码来优化/更改/替换该部分。
-
是的,我正在调查。接下来我将很快为我的整个工作线程执行此操作。我整晚都在评论我的程序的一部分,这个功能无疑会导致巨大的减速。你觉得有什么马上就错了吗?
-
那么您是否尝试使用 midRef 代替?
-
我投票结束这个问题,因为它是关于优化工作代码的,属于Code Review
-
顺便说一句,永远不要在调试模式下测试性能。始终处于优化状态。
标签: c++ qt optimization qstring