您发布的代码中有两个错误,我已更正。
1) 假设您总是想要两个十六进制数字,您想检查该值是否小于 16,而不是 10。
2) QString::setNum 对 char 没有重载,因此该值被提升为更大的类型。对于像 128 这样的值,它在有符号字符中为负数,由于符号扩展,您将得到 x0ffffffffffffff80。
函数foo1 是您修复了错误的原始代码,foo2 是一个更优化的版本,可以避免创建临时的QString,因为转换为 unicode 和返回不是免费的,并且在前面添加值字符串需要额外复制。
我使用了QElapsedTimer,因为在我正在测试它的 Windows 上使用高分辨率 PerformanceCounter 时钟。如果您在另一个平台上,它可能不太准确。您可以在文档中查看它可能使用的不同类型的时钟。
如果您希望打印转换后的字符串以验证它们是否相同,请将 display_converted_string 设置为 true。
#include <QString>
#include <QByteArray>
#include <QElapsedTimer>
#include <iostream>
QByteArray foo1(QByteArray data)
{
QByteArray newData;
for (int i = 0; i < data.size(); i++) {
unsigned char c = data[i];
QString hex;
hex.setNum(c, 16);
if (c < 16) {
hex.prepend("x0");
} else {
hex.prepend("x");
}
newData.append(hex.toLatin1());
}
return newData;
}
QByteArray foo2(QByteArray data)
{
static const char digits[] = {'0','1','2','3','4','5','6','7',
'8','9','a','b','c','d','e','f'};
QByteArray newData;
newData.reserve(data.size() * 3);
for (int i = 0; i < data.size(); i++)
{
unsigned char c = data[i];
newData.append('x');
newData.append(digits[(c >> 4) & 0x0f]);
newData.append(digits[c & 0x0f]);
}
return newData;
}
int main()
{
const int iterations = 10000;
const bool display_converted_string = false;
QElapsedTimer t;
std::cout << "Using clock type " << t.clockType() << ".\n";
QByteArray data(256, 0);
QByteArray newData;
qint64 elapsed1 = 0, elapsed2 = 0;
//Set the values in data to 0-255 to make sure all values are converted properly.
for(int i = 0; i < data.size(); ++i)
{
data[i] = i;
}
t.start();
for(int i = 0; i < iterations; ++i)
{
newData = foo1(data);
}
elapsed1 = t.nsecsElapsed();
std::cout << "foo1 elapsed time = " << elapsed1 << "\n";
if(display_converted_string)
{
std::cout << "newData = " << newData.data() << "\n";
}
t.restart();
for(int i = 0; i < iterations; ++i)
{
newData = foo2(data);
}
elapsed2 = t.nsecsElapsed();
std::cout << "foo2 elapsed time = " << elapsed2 << "\n";
if(display_converted_string)
{
std::cout << "newData = " << newData.data() << "\n";
}
return 0;
}