【发布时间】:2015-08-30 19:09:30
【问题描述】:
假设我们有以下(无意义的)代码:
const int a = 0;
int c = 0;
for(int b = 0; b < 10000000; b++)
{
if(a) c++;
c += 7;
}
变量 'a' 等于 0,因此编译器可以推断出编译时间,指令 'if(a) c++;'永远不会被执行,并且会优化它。
我的问题:lambda 闭包也会发生同样的情况吗?
查看另一段代码:
const int a = 0;
function<int()> lambda = [a]()
{
int c = 0;
for(int b = 0; b < 10000000; b++)
{
if(a) c++;
c += 7;
}
return c;
}
编译器会知道 'a' 是 0 并且会优化 lambda 吗?
更复杂的例子:
function<int()> generate_lambda(const int a)
{
return [a]()
{
int c = 0;
for(int b = 0; b < 10000000; b++)
{
if(a) c++;
c += 7;
}
return c;
};
}
function<int()> a_is_zero = generate_lambda(0);
function<int()> a_is_one = generate_lambda(1);
当编译器知道 'a' 在生成时为 0 时,它会足够聪明地优化第一个 lambda 吗?
gcc 或者 llvm 有这种优化吗?
我之所以问,是因为我想知道当我知道 lambda 生成时间满足某些假设时是否应该手动进行此类优化,或者编译器会为我这样做。
【问题讨论】:
-
你知道gcc.godbolt.org 吗?它几乎可以回答你所有的问题,甚至更多:) -- 此外,
std::function可能不会被优化,因为它的类型擦除目的与内联直接冲突。 -
@Quentin 看穿类型擦除是编译器的热门话题,而且他们在这方面做得还不错。
-
我停止将代码编译到 DLLS 中,因为使用静态库时,编译器大多数时候会优化掉虚拟调用,即使使用 GCC 也会发生这种情况,但我担心这样的问题不是主题^^
-
因为我们有一个memory allocation going on,所以Is the compiler allowed to optimize out heap memory allocations? 的答案可能有助于定义围绕此案例优化的限制。
-
@ShafikYaghmour 它不需要内存分配,一些库实现了优化以存储小型函子而无需分配。
标签: c++ gcc optimization lambda llvm-clang