Por exemplo, eu tenho o seguinte código:
auto z = [](int x) -> int {
if (x > 0) {
switch (x) {
case 2: return 5;
case 3: return 6;
default: return 1;
}
}
return 0;
};
E depois eu chamo isso várias vezes. No código asm, vejo chamadas externas com o lambda .... algo ... Não está sendo fácil ler e acho que também pode causar desempenho. Então, talvez eu ganhe na metaprogramação, mas perco na depuração e no desempenho do asm? Devo evitar recursos modernos de linguagem, macros e outros aspectos de meta programação para garantir a simplicidade de desempenho e depuração?
if
é completamente redundante no código de exemplo e, embora o compilador provavelmente entenda que não há razão para tentar uma previsão de ramificação incorreta.Respostas:
Não , não quando você escreve seu código pela primeira vez e não sofre de problemas reais e mensuráveis de desempenho. Para a maioria das tarefas, esse é o caso padrão. Pensar muito cedo em otimização é chamado de "otimização prematura", e há boas razões pelas quais D. Knuth chamou isso de "a raiz de todo mal" .
Sim , quando você mede um gargalo de desempenho real e comprovável e identifica essa construção lambda específica como a causa raiz. Nesse caso, pode ser uma boa idéia lembrar a "lei das abstrações com vazamentos" de Joel Spolsky e pensar sobre o que pode acontecer no nível asm. Mas tenha cuidado, você pode se surpreender com o quão pequeno será o aumento de desempenho ao substituir uma construção lambda por uma construção de linguagem "não tão moderna" (pelo menos ao usar um compilador C ++ decente).
fonte
A escolha entre lambda e functor-class é uma troca.
O ganho do lambda é principalmente sintático, minimizando a quantidade de clichê e permitindo que o código conceitualmente relacionado seja escrito em linha, dentro da função que o utilizará (imediatamente ou mais tarde).
Em termos de desempenho, isso não é pior do que uma classe functor , que é uma estrutura ou classe C ++ que contém um único "método". De fato, os compiladores tratam o lambda de maneira diferente da classe de functor gerada por compilador nos bastidores.
No seu exemplo de código, em termos de desempenho, não é diferente de uma chamada de função, porque essa classe de functor não possui estado (porque possui uma cláusula de captura vazia), exigindo, portanto, nenhuma alocação, construtor ou destruição.
Depurar qualquer código C ++ não trivial usando um desmontador sempre foi uma tarefa difícil. Isso é verdade com ou sem o uso de lambda. Isso é causado pela sofisticada otimização de código do compilador C ++, que resultou na reordenação, intercalação e eliminação de código morto.
O aspecto de desconfiança de nomes é um pouco desagradável, e o suporte ao depurador para lambda ainda está em sua infância . Só podemos esperar que o suporte ao depurador melhore com o tempo.
Atualmente, a melhor maneira de depurar o código lambda é usar um depurador que suporte a configuração de pontos de interrupção no nível do código-fonte, ou seja, especificando o nome do arquivo de origem e o número da linha.
fonte
Para adicionar à resposta do @DocBrown, lembre-se de que hoje em dia as CPUs são baratas, mas a mão-de-obra é cara.
No custo geral de um programa, o hardware geralmente é trivial em comparação com o custo de manutenção, que é de longe a parte mais cara de um projeto típico (até mais do que seu desenvolvimento).
Portanto, seu código precisa otimizar a manutenção acima de tudo, exceto quando o desempenho é crítico (e mesmo assim a manutenção precisa ser considerada).
fonte