【问题标题】:Qt optimization of a QByteArray conversionQByteArray 转换的 Qt 优化
【发布时间】:2014-07-13 14:36:03
【问题描述】:

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

如何改进这段代码?

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

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

【问题讨论】:

    标签: qt optimization qbytearray


    【解决方案1】:

    如何改进这段代码?

    在优化之前进行基准测试。不要过早优化。

    除了要点:为什么要优化它?

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

    2) 如果您不那么在意性能,那么您应该牢记可读性和可维护性作为主要原则,这样您的代码就可以了。

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

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

    1) Prepender 是个坏名声;它在英语中通常称为“前缀”。

    2) 您希望使用 QChar 而不是 QString 作为字符。

    3) 同样,对于替换,您希望使用 '' 而不是字符串'ish "" 公式。

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

    5) 我什至不会在这里为前缀使用参数,因为它总是相同的,所以它并不真正符合变量的定义。

    6) 无需显式创建临时变量。

    7) 使函数内联。

    因此,你会这样写:

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

    【讨论】:

    • 您也可以选择使用remove(QChar) 方法来方便,就像在 QString 中一样。这甚至会使代码更合乎逻辑,因为您不是替换,而是原则上删除。
    【解决方案2】:

    由于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”)时,此代码可能会出现意外行为。如果有问题,您可以通过某种方式解决此问题。

    【讨论】:

      猜你喜欢
      • 2014-07-13
      • 2016-10-14
      • 1970-01-01
      • 2016-08-14
      • 2017-12-13
      • 2014-12-23
      • 1970-01-01
      • 2019-04-25
      • 2017-06-16
      相关资源
      最近更新 更多