我在 Qt's Doc 中找到了这个:
QStringViews should be passed by value, not by reference-to-const:
他们举了下面的例子:
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
参数作为对象的 address ,则调用这样的函数外联会强制编译器分配一个堆栈上的 QStringView
对象能够将其地址作为成员函数的第一个参数传递。
按值传递还有第二个论点:别名问题较少。作为引用类型,QStringView
无论如何都会出现这个问题,但请考虑 std::complex
:Take
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
可以解决问题。
关于c++ - 为什么按值传递 QStringView 比引用常量更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52364784/