Em seu livro, The C++ Standard Library (Second Edition)
Nicolai Josuttis afirma que as lambdas podem ser melhor otimizadas pelo compilador do que as funções simples.
Além disso, os compiladores C ++ otimizam melhor as lambdas do que as funções comuns. (Página 213)
Por que é que?
Eu pensei que quando se trata de inline não deveria haver mais nenhuma diferença. A única razão pela qual pude pensar é que os compiladores podem ter um melhor contexto local com lambdas e isso pode fazer mais suposições e realizar mais otimizações.
c++
optimization
c++11
lambda
compiler-optimization
Stephan Dollberg
fonte
fonte
Respostas:
O motivo é que lambdas são objetos de função, portanto, passá-los para um modelo de função instancia uma nova função especificamente para esse objeto. O compilador pode, assim, alinhar trivialmente a chamada lambda.
Por outro lado, para funções, aplica-se a antiga advertência: um ponteiro de função é passado para o modelo de função, e os compiladores tradicionalmente têm muitos problemas em incluir chamadas por meio de ponteiros de função. Teoricamente, eles podem ser embutidos, mas apenas se a função circundante também estiver embutida.
Como exemplo, considere o seguinte modelo de função:
Chamando-o com um lambda como este:
Resultados nesta instanciação (criada pelo compilador):
… O compilador sabe
_some_lambda_type::operator ()
e pode fazer chamadas em linha para ele trivialmente. (E invocar a funçãomap
com qualquer outro lambda criaria uma nova instanciação,map
pois cada lambda tem um tipo distinto.)Mas quando chamada com um ponteiro de função, a instanciação é a seguinte:
... e aqui
f
aponta para um endereço diferente para cada chamadamap
e, portanto, o compilador não pode incorporar chamadas paraf
, a menos que a chamada ao redormap
também tenha sido incorporada para que o compilador possa resolverf
uma função específica.fonte
std::sort
é o exemplo clássico disso usando lambdas, em vez de um ponteiro de função, que aumenta em sete vezes (provavelmente mais, mas não tenho dados sobre isso!) o desempenho aumenta.std::sort
, oumap
no meu exemplo) eo próprio lambda. A lambda é geralmente pequena. A outra função - não necessariamente. Estamos preocupados em incluir chamadas para o lambda dentro da outra função.pred
cuja definição é visível e o uso do gcc v5.3,std::find_if(b, e, pred)
não está alinhadopred
, masstd::find_if(b, e, [](int x){return pred(x);})
sim. Clang consegue alinhar ambos, mas não produz código tão rápido quanto g ++ com o lambda.Porque quando você passa uma "função" para um algoritmo, na verdade você está passando um ponteiro para funcionar, de modo que ele precisa fazer uma chamada indireta via ponteiro para a função. Quando você usa um lambda, você está passando um objeto para uma instância de modelo especialmente instanciada para esse tipo e a chamada para a função lambda é uma chamada direta, não uma chamada por meio de um ponteiro de função, portanto, é muito provável que seja embutida.
fonte