Qt优化QByteArray转换

时间:2014-05-24 08:03:23

标签: qt optimization qbytearray

我写了一个函数来将一些二进制数据的十六进制字符串表示(如x00)转换为数据本身。

如何改进此代码?

QByteArray restoreData(const QByteArray &data, const QString prepender = "x")
{
    QByteArray restoredData = data;

    return QByteArray::fromHex(restoredData.replace(prepender, ""));
}

2 个答案:

答案 0 :(得分:1)

由于replace(),您的代码存在性能问题。替换本身并不是非常快,并且创建中间QByteArray对象会使代码更慢。如果您真的关心性能,可以从Qt源复制QByteArray::fromHex实施,并根据您的需要进行修改。幸运的是,它的实现非常独立。我只将/ 2更改为/ 3并添加--i行以跳过“x”字符。

QByteArray myFromHex(const QByteArray &hexEncoded)
{
    QByteArray res((hexEncoded.size() + 1)/ 3, Qt::Uninitialized);
    uchar *result = (uchar *)res.data() + res.size();

    bool odd_digit = true;
    for (int i = hexEncoded.size() - 1; i >= 0; --i) {
        int ch = hexEncoded.at(i);
        int tmp;
        if (ch >= '0' && ch <= '9')
            tmp = ch - '0';
        else if (ch >= 'a' && ch <= 'f')
            tmp = ch - 'a' + 10;
        else if (ch >= 'A' && ch <= 'F')
            tmp = ch - 'A' + 10;
        else
            continue;
        if (odd_digit) {
            --result;
            *result = tmp;
            odd_digit = false;
        } else {
            *result |= tmp << 4;
            odd_digit = true;
            --i;
        }
    }

    res.remove(0, result - (const uchar *)res.constData());
    return res;
}

测试:

qDebug() << QByteArray::fromHex("54455354"); // => "TEST"
qDebug() << myFromHex("x54x45x53x54"); // => "TEST"

hexEncoded格式错误时(例如,“x54x45x5”将转换为“TU”),此代码可能会出现意外行为。如果这是一个问题,你可以以某种方式解决这个问题。

答案 1 :(得分:1)

  

如何改进此代码?

优化此前的基准测试。不要过早优化。

超越要点:你为什么要优化它?

1)如果您真的关心性能,从性能角度来看这个可忽略不计的代码很重要,那么您首先不会使用Qt,因为与优化良好的框架相比,Qt本质上很慢。

2)如果您不关心性能,那么您应该将可读性和维护作为主导原则,在这种情况下您的代码就可以了。

您还没有展示任何真实世界的示例,无论您想要优化的原因。这感觉就像一个学术问题,对我来说没什么实际用处。了解更多关于动机的信息会很有趣。

话虽如此,一些改进项目也是优化,可以在你的代码中完成,但是又一次:它不是为了优化而做的,而是更像逻辑原因。

1)Prepender是坏名字;它通常被称为&#34;前缀&#34;用英语。

2)您希望使用QChar而不是QString作为角色。

3)同样,对于替换,您希望使用&#39;&#39;而不是字符串&#39; ish&#34;&#34;式。

4)即使它是CoW(隐式共享),我也会使用引用传递类,而不是值语义。

5)我甚至不会在这里使用参数作为前缀,因为它始终是相同的,因此它并不真正适合变量的定义。

6)明确地创建一个临时变量是不必要的。

7)使函数内联。

因此,你会写这样的东西:

QByteArray restoreData(QByteArray data)
{
    return QByteArray::fromHex(data.replace('x', ''));
}