【发布时间】:2020-11-14 09:57:32
【问题描述】:
作为一个简化的示例,假设我从以下代码开始:
void function1 (Object &myObject) {
for (int b = 0; b < 10000; b++) {
// ... a bunch of code that uses the below myFunction(int, int) in different ways
auto x = myObject.myFunction(12345, b);
// do something with x and etc
}
}
我想要做的是获取 for 循环中的内容,将其放入一个单独的内联函数中,然后以某种方式授予该函数访问 myObject.myFunction(a, b) 的柯里化版本的权限,其中 b 已经存在设置。
这样做的一种方法是:
__attribute__((always_inline))
inline void function2 (Object &myObject, int &b) {
#define curried(a) myObject.myFunction(a, b)
// ... a bunch of code that uses the below function in different ways
auto x = curried(12345);
// do something with x and etc
}
void function1 (Object &myObject) {
for (int b = 0; b < 10000; b++) {
function2(myObject, b);
}
}
如果您可以让编译器成功内联function2,则生成相同的汇编代码而没有开销。 (即使使用了__attribute__((always_inline)),这可能至少需要-O1 或-O2,至少使用clang。)
无论如何,在这种情况下使用宏有点尴尬,并且必须将b 的值从function1 传递给function2。将 lambda 函数作为参数传递给 function2 会更好,但后来我遇到了捕获问题(您只能传递未捕获的 lambda,但我们需要捕获 myObject) ,以及一些额外的开销。例如,我想这样做:
__attribute__((always_inline))
inline void function2 (some_type curried) {
// ... a bunch of code that uses the below function in different ways
auto x = curried(12345);
// do something with x and etc
}
void function1 (Object &myObject) {
for (int b = 0; b < 10000; b++) {
auto lambda = [&](int a) {return myObject.myFunction(a, n);};
function2(lambda);
}
}
但这会失败,除非 lambda 没有捕获,因为没有适合“some_type”的类型。
所以我的问题:
是否有任何正确的方法来做到这一点,而且开销为零,至少进行了一些最小的优化?
【问题讨论】:
-
为什么不使用 lambda:
auto curried = [&](auto a) { return myObject.myFunction(a, b);}? -
您是否在优化开启的情况下进行编译?
-
inline只是一个建议。由编译器决定它是否应该实际内联调用。' -
你的内联与
function2有关,它对myObject.myFunction(12345, b)的调用没有影响。实际上,您只是添加了编译器可能无法完全优化的另一层 - 而不是直接调用它 - 这可能是增加开销的原因
标签: c++ optimization lambda c++17 currying