如何帮助编译器优化 lambda 调用?
How to help the compiler to optimize lambda calls?
当允许将数据结构遍历提取到单独的函数时,lambda 的使用可以极大地提高代码的可读性。这是一个最小的例子:
static inline void forXY(int v, std::function<void(int,int)> body) noexcept {
for(int y = 0 ; y<v ; y++) {
for(int x = 0 ; x<v ; x++) {
body(x, y);
}
}
}
static void job() noexcept {
forXY(100, [](int x, int y) { printf("%d %d\n", y, x); });
}
然而,即使在这种一切都在控制之下的简单情况下(-O3、没有其他调用站点、没有捕获、没有模板、没有外部符号、没有导出符号、没有异常),编译器 (clang 12.0. 5 在我的例子中)没有优化 lambda 调用。
我是不是漏掉了什么明显的东西?也许我的代码中有些东西阻止编译器检测到内联函数会导致相同的行为?
Do not use std::function
, use templated argument for body so the compiler can actually see the lambda when compiling forXY
. Otherwise it resorts to type erasure and virtual calls inside std::function
. – yeputons
利用这个思路,改进后的代码如下:
template <typename F>
static inline void forXY(int v, F body) noexcept {
for(int y = 0 ; y<v ; y++) {
for(int x = 0 ; x<v ; x++) {
body(x, y);
}
}
}
当允许将数据结构遍历提取到单独的函数时,lambda 的使用可以极大地提高代码的可读性。这是一个最小的例子:
static inline void forXY(int v, std::function<void(int,int)> body) noexcept {
for(int y = 0 ; y<v ; y++) {
for(int x = 0 ; x<v ; x++) {
body(x, y);
}
}
}
static void job() noexcept {
forXY(100, [](int x, int y) { printf("%d %d\n", y, x); });
}
然而,即使在这种一切都在控制之下的简单情况下(-O3、没有其他调用站点、没有捕获、没有模板、没有外部符号、没有导出符号、没有异常),编译器 (clang 12.0. 5 在我的例子中)没有优化 lambda 调用。
我是不是漏掉了什么明显的东西?也许我的代码中有些东西阻止编译器检测到内联函数会导致相同的行为?
Do not use
std::function
, use templated argument for body so the compiler can actually see the lambda when compilingforXY
. Otherwise it resorts to type erasure and virtual calls insidestd::function
. – yeputons
利用这个思路,改进后的代码如下:
template <typename F>
static inline void forXY(int v, F body) noexcept {
for(int y = 0 ; y<v ; y++) {
for(int x = 0 ; x<v ; x++) {
body(x, y);
}
}
}