我正在使用 C++ lambdas 进行编程。出于性能原因,我想确保对 lambda 的调用由编译器内联。例如,我有这段简化的代码:
template <typename T>
auto gen_fn1(T x1, T x2) {
auto fn1 = [x1, x2]() {
return x1 + x2;
};
return fn1;
}
template <typename T>
auto gen_fn2(T x1, T x2) {
auto fn2 = [x1, x2]() {
auto fn1 = gen_fn1(x1, x2);
return fn1() * fn1();
};
return fn2;
}
int test_1() {
auto fn2 = gen_fn2(1, 2);
return fn2();
}
Run Code Online (Sandbox Code Playgroud)
我想确保 test_1() 中的 lambda 生成和调用不会引入额外的成本。我可以手动检查编译生成的汇编代码。通过 clang++8 的“-O2”优化,我可以看到预期的结果:在生成的代码中几乎只是“返回 9”。所以我的问题是:有没有办法自动检查我总能得到想要的结果?特别是,我想检查:
问题 2 对我来说更有趣。能够以可编程的方式检查它是最值得赞赏的,例如'assert(gen_fn2(1, 2) == ()[]{ return 9; }'。如果不可能,检查编译器的中间文件也有帮助, 或程序集文件。但是如何呢?
首先,正如其他答案所指出的,C++ lambda 基本上是带有operator()
方法的匿名类;所以,你的问题与“有没有办法检查对象方法的某个调用是否被内联?”没有什么不同。
方法调用是否内联是编译器的选择,并且不是语言规范强制要求的(尽管在某些情况下不可能内联)。因此,这一事实并未在语言本身中体现(也没有在语言的编译器扩展中体现)。
您可以做以下两件事之一:
gcc -S
或clang++ -S
,加上任何优化标志和其他编译选项。但请记住,即使在编译期间没有发生内联,理论上它仍然可能发生在链接处-时间。