c++ - 为什么按值传递 QStringView 比引用 const 更快?
问题描述
我在Qt 的 Doc中找到了这个:
QStringViews 应该通过值传递,而不是通过引用到常量:
他们给出了以下示例:
void myfun1(QStringView sv); // preferred
void myfun2(const QStringView &sv); // compiles and works, but slower
这怎么可能?
解决方案
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()
在第一行之后大打出手,从而计算出错误的结果(是的,人们确实在生产中编写了此代码)。传递rhs
by 值会使问题消失。