为什么按值传递 QStringView 比引用 const 更快?

Sca*_*cab 5 c++ qt

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

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

他们给出了以下示例:

void myfun1(QStringView sv);        // preferred
void myfun2(const QStringView &sv); // compiles and works, but slower
Run Code Online (Sandbox Code Playgroud)

这怎么可能?

Mar*_*utz 5

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

\n\n

在几乎所有 C++ 编译器中,QStringView对象都表示为一对 CPU 寄存器,并且许多 C++ ABI(不幸的是,不包括 Windows)支持将 CPU 寄存器中的此类类型传递给函数。如果您编写成员函数 na\xc3\xafvely,并使用隐式this参数作为对象的地址,则外联调用此类函数将强制编译器QStringView在堆栈上分配一个对象,以便能够传递其地址作为成员函数的第一个参数。

\n\n

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

\n\n
std::complex &operator*=(std::complex &lhs, const std::complex &rhs);\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
std::complex c = 3 + 4i;\nc *= c;\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您将\xc3\xafvely 实现operator*=为数学函数:

\n\n
auto r = real(), i = imag();\nm_real = r * other.real() - i * other.imag();\nm_imag = r * other.imag() + i * other.real();\n
Run Code Online (Sandbox Code Playgroud)\n\n

你会other.real()在第一行之后崩溃,从而计算出错误的结果(是的,人们确实在生产中编写了这段代码)。按值传递rhs可以使问题消失。

\n