Eu constantemente ouço o quão ruim é a reflexão. Enquanto geralmente evito a reflexão e raramente encontro situações em que é impossível resolver meu problema sem ela, fiquei pensando ...
Para aqueles que usaram a reflexão em aplicativos, você mediu o desempenho e é realmente tão ruim?
c#
.net
performance
reflection
Dan Herbert
fonte
fonte
Respostas:
Isto é. Mas isso depende do que você está tentando fazer.
Uso reflexão para carregar dinamicamente assemblies (plugins) e seu desempenho "penalidade" não é um problema, pois a operação é algo que faço durante a inicialização do aplicativo.
No entanto, se você estiver refletindo dentro de uma série de loops aninhados com chamadas de reflexão em cada um, eu diria que você deve revisitar seu código :)
Para operações "algumas vezes", a reflexão é perfeitamente aceitável e você não notará nenhum atraso ou problema com ela. É um mecanismo muito poderoso e é usado até pelo .NET. Por isso, não vejo por que você não deveria tentar.
fonte
Em sua palestra O desempenho das coisas cotidianas , Jeff Richter mostra que chamar um método pela reflexão é cerca de 1000 vezes mais lento do que chamá-lo normalmente.
Dica de Jeff: se você precisar chamar o método várias vezes, use a reflexão uma vez para encontrá-lo, atribua-o a um delegado e ligue para o delegado.
fonte
O desempenho da reflexão dependerá da implementação (chamadas repetitivas devem ser armazenadas em cache, por exemplo:)
entity.GetType().GetProperty("PropName")
. Como a maior parte da reflexão que vejo diariamente é usada para preencher entidades de leitores de dados ou outras estruturas de tipo de repositório, decidi avaliar o desempenho especificamente na reflexão quando é usado para obter ou definir propriedades de objetos.Eu criei um teste que considero justo, pois armazena em cache todas as chamadas repetidas e apenas vezes a chamada SetValue ou GetValue real. Todo o código-fonte para o teste de desempenho está em bitbucket em: https://bitbucket.org/grenade/accessortest . O escrutínio é bem-vindo e incentivado.
A conclusão a que cheguei é que não é prático e não fornece melhorias visíveis no desempenho para remover a reflexão em uma camada de acesso a dados que retorna menos de 100.000 linhas por vez quando a implementação da reflexão é bem-sucedida.
O gráfico acima demonstra o resultado da minha pequena referência e mostra que os mecanismos que superam a reflexão só o fazem visivelmente após a marca de 100.000 ciclos. A maioria dos DALs retorna apenas várias centenas ou talvez milhares de linhas por vez e, nesses níveis, a reflexão funciona muito bem.
fonte
Se você não estiver em um loop, não se preocupe.
fonte
Minha experiência mais pertinente foi escrever código para comparar duas entidades de dados do mesmo tipo em um modelo de objeto grande em termos de propriedades. Entendi, tentei, corri como um cachorro, obviamente.
Fiquei desanimado e, durante a noite, percebi que, sem alterar a lógica, eu poderia usar o mesmo algoritmo para gerar automaticamente métodos para fazer a comparação, mas acessar estaticamente as propriedades. Não demorou muito tempo para adaptar o código para esse fim, e eu tive a capacidade de fazer uma comparação profunda de propriedades com entidades com código estático que podia ser atualizado com o clique de um botão sempre que o modelo de objeto era alterado.
O que quero dizer é: nas conversas com colegas, já que várias vezes indiquei que o uso da reflexão poderia ser para gerar automaticamente código para compilar, em vez de executar operações de tempo de execução, e isso geralmente vale a pena considerar.
fonte
Não massivamente. Eu nunca tive um problema com isso no desenvolvimento de desktop, a menos que, como Martin declara, você o esteja usando em um local tolo. Ouvi dizer que muitas pessoas têm medos totalmente irracionais sobre seu desempenho no desenvolvimento de desktops.
No Compact Framework (no qual geralmente estou), é praticamente um anátema e deve ser evitado como a praga na maioria dos casos. Ainda posso usá-lo com pouca frequência, mas tenho que ter muito cuidado com a aplicação, que é bem menos divertida. :(
fonte
É ruim o suficiente que você precise se preocupar até com a reflexão feita internamente pelas bibliotecas .NET para obter um código crítico de desempenho.
O exemplo a seguir é obsoleto - verdadeiro na época (2008), mas há muito tempo corrigido nas versões CLR mais recentes. A reflexão em geral ainda é uma coisa um pouco cara!
Caso em questão: você nunca deve usar um membro declarado como "Objeto" em uma instrução de bloqueio (C #) / SyncLock (VB.NET) no código de alto desempenho. Por quê? Como o CLR não pode bloquear um tipo de valor, o que significa que ele precisa fazer uma verificação do tipo de reflexão em tempo de execução para ver se o seu Objeto é realmente um tipo de valor em vez de um tipo de referência.
fonte
Como em todas as coisas da programação, você precisa equilibrar o custo de desempenho com qualquer benefício obtido. A reflexão é uma ferramenta inestimável quando usada com cuidado. Criei uma biblioteca de mapeamento de O / R em C # que usava reflexão para fazer as ligações. Isso funcionou extraordinariamente bem. A maior parte do código de reflexão foi executada apenas uma vez; portanto, qualquer ocorrência de desempenho foi bastante pequena, mas os benefícios foram excelentes. Se eu estivesse escrevendo um novo algoritmo de classificação desordenado, provavelmente não usaria a reflexão, pois provavelmente teria uma escala ruim.
Compreendo que não respondi exatamente à sua pergunta aqui. O que quero dizer é que isso realmente não importa. Use a reflexão quando apropriado. É apenas mais um recurso do idioma que você precisa aprender como e quando usar.
fonte
A reflexão pode ter um impacto notável no desempenho se você a usar para criação de objetos frequentes. Desenvolvi aplicativos com base no Composite UI Application Block, que depende muito da reflexão. Houve uma degradação perceptível no desempenho relacionada à criação de objetos via reflexão.
No entanto, na maioria dos casos, não há problemas com o uso da reflexão. Se sua única necessidade é inspecionar alguma montagem, eu recomendaria o Mono.Cecil, que é muito leve e rápido
fonte
A reflexão é cara devido às muitas verificações que o tempo de execução deve fazer sempre que você solicita um método que corresponda a uma lista de parâmetros. Em algum lugar profundo, existe um código que percorre todos os métodos de um tipo, verifica sua visibilidade, verifica o tipo de retorno e também o tipo de cada parâmetro. Tudo isso custa tempo.
Quando você executa esse método internamente, existe algum código que faz coisas como verificar se você passou uma lista compatível de parâmetros antes de executar o método de destino real.
Se possível, é sempre recomendável que você armazene em cache o identificador do método para reutilizá-lo continuamente no futuro. Como todas as boas dicas de programação, geralmente faz sentido evitar se repetir. Nesse caso, seria um desperdício procurar continuamente o método com determinados parâmetros e executá-lo sempre.
Dê uma olhada na fonte e veja o que está sendo feito.
fonte
Como em tudo, trata-se de avaliar a situação. No DotNetNuke, existe um componente bastante básico chamado
FillObject
que usa reflexão para preencher objetos de datarows.Esse é um cenário bastante comum e há um artigo no MSDN, Usando o Reflection para vincular objetos de negócios a controles de formulário do ASP.NET, que aborda os problemas de desempenho.
Desempenho à parte, uma coisa que eu não gosto em usar a reflexão nesse cenário específico é que ele tende a reduzir a capacidade de entender o código rapidamente, o que para mim não parece valer o esforço quando você considera que também perde a compilação segurança de tempo, em oposição a conjuntos de dados fortemente tipados ou algo como LINQ to SQL .
fonte
O Reflexo não diminui drasticamente o desempenho do seu aplicativo. Você pode fazer algumas coisas mais rapidamente, sem usar a reflexão, mas se a Reflexão for a maneira mais fácil de obter alguma funcionalidade, use-a. Você sempre pode refatorar seu código do Reflection se ele se tornar um problema de desempenho.
fonte
Eu acho que você vai achar que a resposta é, depende. Não é grande coisa se você quiser colocá-lo em seu aplicativo de lista de tarefas. É importante se você quiser colocá-lo na biblioteca de persistência do Facebook.
fonte