【问题标题】:How to optimize this Qt code (QByteArray conversion)?如何优化这个 Qt 代码(QByteArray 转换)?
【发布时间】:2014-07-13 13:00:10
【问题描述】:

我需要对二进制数据执行一些正则表达式操作。我编写了一个函数来将 QByteArray 数据转换为六进制字符串表示形式。每个字节都以“x”开头,用于解析目的。

如何优化这段代码?

QByteArray data;
QByteArray newData;

for (int i = 0; i < data.size(); i++) {

    QString hex;
    hex.setNum(data[i], 16);

    if (data[i] < 10) {

        hex.prepend("x0");

    } else {

        hex.prepend("x");
    }

    newData.append(hex.toLatin1());
}

【问题讨论】:

  • 这个问题似乎跑题了,因为它是关于代码审查的。

标签: qt optimization


【解决方案1】:

您发布的代码中有两个错误,我已更正。

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;
}

【讨论】:

    猜你喜欢
    • 2014-07-13
    • 2014-12-23
    • 2017-07-13
    • 1970-01-01
    • 1970-01-01
    • 2017-06-16
    • 2010-12-14
    • 2011-11-10
    • 1970-01-01
    相关资源
    最近更新 更多