首页 > 解决方案 > 为什么按值传递 QStringView 比引用 const 更快?

问题描述

我在Qt 的 Doc中找到了这个:

QStringViews 应该通过值传递,而不是通过引用到常量:

他们给出了以下示例:

void myfun1(QStringView sv);        // preferred
void myfun2(const QStringView &sv); // compiles and works, but slower

这怎么可能?

标签: c++qt

解决方案


QStringView通常用于高性能代码中,QString由于涉及的内存分配,创建实际对象会很慢。我进行了优化QStringView,使其与(const QChar*, size_t)手动处理一样高效。我什至将成员函数调用内联传递给自由函数,*this按值传递。所有这些都是为了避免将QStringView对象强制放入堆栈,或者更一般地说,强制放入内存。

在几乎所有 C++ 编译器中,QStringView对象都表示为一对 CPU 寄存器,并且许多 C++ ABI(遗憾的是,不包括 Windows)支持将 CPU 寄存器中的此类类型传递给函数。如果您天真地编写了成员函数,并使用隐式this参数作为对象的地址,那么离线调用这样的函数将迫使编译器QStringView在堆栈上分配一个对象,以便能够将其地址作为第一个参数传递的成员函数。

值传递还有第二个论点:别名问题较少。作为参考类型,QStringView无论如何都会出现该问题,但std::complex请考虑:

std::complex &operator*=(std::complex &lhs, const std::complex &rhs);

(为简洁起见,省略了模板参数)。这可以这样调用:

std::complex c = 3 + 4i;
c *= c;

如果您天真地实现operator*=它,就好像它是一个数学函数:

auto r = real(), i = imag();
m_real = r * other.real() - i * other.imag();
m_imag = r * other.imag() + i * other.real();

您会other.real()在第一行之后大打出手,从而计算出错误的结果(是的,人们确实在生产中编写了此代码)。传递rhsby 值会使问题消失。


推荐阅读