这是一个非常笼统的c++
问题。考虑以下两个 block (它们做同样的事情):
v_od=((x-wOut*svd.matrixV().topLeftCorner(p,Q).adjoint()).cwiseAbs2().rowwise().sum()).array().sqrt();
和
MatrixXd wtemp=(x-wOut*svd.matrixV().topLeftCorner(p,Q).adjoint());
v_od=(wtemp.cwiseAbs2().rowwise().sum()).array().sqrt();
现在第一个结构感觉更有效率。但这是真的吗,
或者 c++ 编译器会将它们编译成相同的东西(我假设编译器是一个好的编译器并且打开了所有安全优化标志。为了论证 wtemp
的大小适中,比如包含 100k 个元素的矩阵)?
我知道对此的一般答案是“对其进行基准测试然后返回给我们” 但我想要一个笼统的答案。
最佳答案
在两种情况下,您的第二个表达式的效率可能根本低于第一个。
第一种情况是 MatrixXd
类的编写者对 cwiseAbs2()
上的重载做了右值引用。在第一个代码中,我们调用方法的值是一个临时值,在第二个代码中它不是。我们可以通过简单地将第二个表达式更改为来解决此问题:
v_od=(std::move(wtemp).cwiseAbs2().rowwise().sum()).array().sqrt();
将 wtemp
转换为右值引用,并基本上告诉 cwiseAbs2()
它所调用的矩阵可以作为暂存空间重复使用。只有如果 MatrixXd
类的编写者实现了这一特定功能,这才有意义。
如果 MatrixXd
类的编写者对几乎所有列出的操作都使用表达式模板,则它可能从根本上变慢的第二种可能方式。这种技术构建了操作的解析树,并且只有在最后将结果分配给一个值时才最终确定所有这些操作。
一些表达式模板被编写来处理能够存储在这样的中间对象中:
auto&& wtemp=(x-wOut*svd.matrixV().topLeftCorner(p,Q).adjoint());
v_od=(std::move(wtemp).cwiseAbs2().rowwise().sum()).array().sqrt();
第一行存储表达式模板 wtemp
而不是将其计算为矩阵,第二行使用第一个中间结果。如果您尝试执行上述操作,其他表达式模板实现会严重崩溃。
表达式模板也是矩阵类编写者必须专门实现的东西。这又是一种有点晦涩的技术——它主要用于通过看似廉价的操作(如字符串追加)来扩展缓冲区的情况。
除非这两种情况,否则性能上的任何差异都将纯粹是“噪音”——没有理由先验地期望编译器或多或少地被其中一种情况混淆。
而且这两者都是相对先进/现代的技术。
它们都不会在库作者明确完成的情况下“由编译器”实现。
关于c++ - 使用临时变量将单行拆分为多行是否会影响性能,即通过抑制某些优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26631281/