Como você faz "funções embutidas" em c #? Acho que não entendo o conceito. Eles são como métodos anônimos? Como funções lambda?
Nota : As respostas tratam quase inteiramente da capacidade de incorporar funções , como "uma otimização manual ou do compilador que substitui um site de chamada de função pelo corpo do receptor". Se você estiver interessado em funções anônimas (também conhecidas como lambda) , consulte a resposta do @ jalf ou Em que é esse 'Lambda' que todo mundo continua falando? .
c#
optimization
inline
Dinah
fonte
fonte
Respostas:
Finalmente, no .NET 4.5, o CLR permite sugerir / sugerir 1 método embutido usando
MethodImplOptions.AggressiveInlining
value. Também está disponível no porta-malas do Mono (confirmado hoje).1 . Anteriormente "força" era usada aqui. Como houve alguns votos negativos, tentarei esclarecer o termo. Como nos comentários e na documentação,
The method should be inlined if possible.
Especialmente considerando o Mono (que está aberto), existem algumas limitações técnicas mono-específicas, considerando inlining ou mais gerais (como funções virtuais). No geral, sim, essa é uma dica para o compilador, mas acho que foi o que foi solicitado.fonte
Os métodos embutidos são simplesmente uma otimização do compilador, onde o código de uma função é rolado no chamador.
Não há mecanismo para fazer isso em C #, e eles devem ser usados com moderação nos idiomas em que são suportados - se você não sabe por que eles devem ser usados em algum lugar, eles não deveriam.
Editar: para esclarecer, há duas razões principais pelas quais elas precisam ser usadas com moderação:
É melhor deixar as coisas em paz e deixar o compilador fazer o seu trabalho; em seguida, faça um perfil e descubra se a linha é a melhor solução para você. Obviamente, algumas coisas fazem sentido para serem incorporadas (principalmente operadores matemáticos), mas deixar o compilador lidar com isso é normalmente a melhor prática.
fonte
Atualização: de acordo com a resposta de konrad.kruczynski , o seguinte é verdadeiro para versões do .NET até 4.0, inclusive.
Você pode usar a classe MethodImplAttribute para impedir que um método seja incorporado.
... mas não há como fazer o oposto e forçar a inclusão.
fonte
GetExecutingAssembly
eGetCallingAssembly
pode fornecer resultados diferentes, dependendo se o método está embutido. Forçar um método a não ser alinhado elimina qualquer incerteza.Você está misturando dois conceitos separados. A função inlining é uma otimização de compilador que não tem impacto na semântica. Uma função se comporta da mesma forma, seja embutida ou não.
Por outro lado, funções lambda são puramente um conceito semântico. Não há requisitos sobre como eles devem ser implementados ou executados, desde que sigam o comportamento estabelecido nas especificações de idioma. Eles podem ser incorporados se o compilador JIT desejar ou não.
Não há palavra-chave embutida em C #, porque é uma otimização que geralmente pode ser deixada para o compilador, especialmente nas linguagens JIT. O compilador JIT tem acesso às estatísticas de tempo de execução, o que permite decidir o que incorporar com muito mais eficiência do que você pode escrever ao escrever o código. Uma função será incorporada se o compilador decidir, e não há nada que você possa fazer sobre isso de qualquer maneira. :)
fonte
Você quer dizer funções embutidas no sentido de C ++? Em que o conteúdo de uma função normal é automaticamente copiado em linha para o local da chamada? O efeito final é que nenhuma chamada de função realmente acontece ao chamar uma função.
Exemplo:
Se sim, então não, não há C # equivalente a isso.
Ou você quer dizer funções declaradas em outra função? Nesse caso, sim, o C # suporta isso por métodos anônimos ou expressões lambda.
Exemplo:
fonte
Cody está certo, mas quero fornecer um exemplo do que é uma função embutida.
Digamos que você tenha este código:
O
otimizadorJust-In-Time docompiladorpode optar por alterar o código para evitar repetidamente fazer uma chamada para OutputItem () na pilha, de modo que seria como se você tivesse escrito o código dessa maneira:Nesse caso, diríamos que a função OutputItem () estava embutida. Observe que isso pode ser feito mesmo que o OutputItem () seja chamado de outros lugares também.
Editado para mostrar um cenário com maior probabilidade de ser incorporado.
fonte
Sim Exatamente, a única distinção é o fato de retornar um valor.
Simplificação (sem usar expressões):
List<T>.ForEach
Executa uma ação, não espera um resultado de retorno.Portanto, um
Action<T>
delegado seria suficiente .. diga:é o mesmo que dizer:
a diferença é que o tipo de parâmetro e a decleração de delegação são inferidos pelo uso e as chaves não são necessárias em um método embutido simples.
Enquanto que
List<T>.Where
Tem uma função, esperando um resultado.Portanto,
Function<T, bool>
seria de se esperar:que é o mesmo que:
Você também pode declarar esses métodos embutidos e atribuí-los às variáveis IE:
ou
Eu espero que isso ajude.
fonte
Há ocasiões em que desejo forçar o código a ser alinhado.
Por exemplo, se eu tenho uma rotina complexa em que há um grande número de decisões tomadas dentro de um bloco altamente iterativo e essas decisões resultam em ações semelhantes, mas ligeiramente diferentes, a serem executadas. Considere, por exemplo, um comparador de classificação complexo (não controlado pelo DB), em que o algoritmo de classificação classifica os elementos de acordo com vários critérios diferentes, como se poderia classificar palavras de acordo com critérios gramaticais e semânticos para um idioma rápido sistema de reconhecimento. Eu tenderia a escrever funções auxiliares para lidar com essas ações, a fim de manter a legibilidade e a modularidade do código-fonte.
Eu sei que essas funções auxiliares devem estar alinhadas, porque é dessa maneira que o código seria escrito se nunca tivesse que ser entendido por um humano. Eu certamente gostaria de garantir, neste caso, que não houvesse nenhuma função chamando sobrecarga.
fonte
A afirmação "é melhor deixar essas coisas em paz e deixar que o compilador faça o trabalho .." (Cody Brocious) é uma loucura completa. Estou programando código de jogo de alto desempenho há 20 anos e ainda preciso encontrar um compilador que seja 'inteligente o suficiente' para saber qual código deve ser incorporado (funções) ou não. Seria útil ter uma declaração "embutida" em c #, a verdade é que o compilador simplesmente não possui todas as informações necessárias para determinar qual função deve estar sempre embutida ou não sem a dica "embutida". Certamente, se a função é pequena (acessador), ela pode ser automaticamente incorporada, mas e se houver algumas linhas de código? Sem sentido, o compilador não tem como saber, você não pode deixar isso para o compilador por código otimizado (além dos algoritmos).
fonte
Eu sei que esta pergunta é sobre c #. No entanto, você pode escrever funções embutidas no .NET com F #. veja: Uso de `inline` em F #
fonte
Não, não existe essa construção em C #, mas o compilador .NET JIT pode decidir fazer chamadas de função em linha no tempo JIT. Mas na verdade não sei se realmente está fazendo essas otimizações.
(Eu acho que deveria :-))
fonte
Caso suas montagens sejam geradas, você pode dar uma olhada no TargetedPatchingOptOut. Isso ajudará a ngen a decidir se métodos embutidos.Referência MSDN
Ainda é apenas uma dica declarativa para otimizar, não um comando imperativo.
fonte
Expressões lambda são funções embutidas! Eu acho que o C # não tem um atributo extra como inline ou algo assim!
fonte
O C # não oferece suporte a métodos (ou funções) embutidos da mesma maneira que linguagens dinâmicas como o python. No entanto, métodos anônimos e lambdas podem ser usados para fins semelhantes, inclusive quando você precisa acessar uma variável no método que contém, como no exemplo abaixo.
fonte