Pergunta

Algumas pessoas argumentaram que o recurso C# 4.0 introduzido com o dynamic A palavra -chave é a mesma que o recurso "tudo é um objeto" do VB. No entanto, qualquer chamada em uma variável dinâmica será traduzida em um delegado de uma vez por isso, o delegado será chamado. Em VB, ao usar Object, nenhum cache é aplicado e cada chamada em um método não talhado envolve muita reflexão sob a altura, às vezes totalizando uma grande penalidade de desempenho de 400 vezes.

Tenha o Otimização e cache de delegados de tipo dinâmico Também foi adicionado às chamadas de método não tipped ou é o objeto não vinculado do VB ainda é tão lento?

Foi útil?

Solução

Solução

Algumas pesquisas e uma melhor leitura do anteriormente referido ao artigo Mencionado por Hans Passant, traz a seguinte conclusão:

  • O VB.NET 2010 suporta o DLR;
  • Você pode implementar IDynamicMetaObjectProvider Se você deseja apoiar explicitamente a dinâmica, o VB.NET Compiler será atualizado para reconhecer isso;
  • VB's Object usará apenas o cache de DLR e método se o objeto implementar IDynamicMetaObjectProvider;
  • Os tipos de BCL e estrutura não implementam IDynamicMetaObjectProvider, usando Object Nesses tipos ou seus próprios tipos, invocarão o vb.net tardio clássico e não com face.

Antecedentes: Elaborando por que o cache de ligação tardia pode ajudar o desempenho do código VB

Algumas pessoas (entre as quais Hans Passant, veem sua resposta) podem se perguntar por que o cache ou o não-cache de ligação tardia poderia importar. Na verdade, faz uma grande diferença, tanto no VB quanto em outras tecnologias de ligação tardia (lembre-se IQueryInterface com com?).

A ligação tardia se resume a um princípio simples: dado um nome e seus parâmetros-deClarações, percorre todos os métodos desta classe e suas classes pais por meio de métodos disponíveis, embora o Type interface (e em VB, um método, uma propriedade e um campo podem olhar o mesmo, tornando esse processo ainda mais lento). Se você considerar que as tabelas de método não são ordenadas, isso é facilmente muito mais caro do que um único método direto (ou seja, digitado).

Se você era capaz de procurar o método uma vez e, em seguida, armazenar o ponteiro do método em uma tabela de pesquisa, isso aceleraria bastante esse processo. A ligação do método em cache no DLR segue uma etapa e substitui a chamada do método por um ponteiro para o método real, se possível. Após a primeira chamada, isso se torna uma ordem de magnitude mais rápida para cada chamada subsequente (pense em 200x a 800x vezes mais rápido).

Como exemplo de quando isso importa, aqui está algum código que ilustra esse problema. Em um caso em que todas as aulas têm um .Name Propriedade da String, mas as classes não compartilham um ancestral ou interface comum, você pode classificar ingenuamente listas de qualquer um desses tipos como assim:

' in the body of some method '
List<Customers> listCustomers = GetListCustomers()
List<Companies> listCompanies = GetListCompanies()

listCustomers.Sort(MySort.SortByName)
listCompanies.Sort(MySort.SortByName)

' sorting function '
Public Shared Function SortByName(Object obj1, Object obj2) As Integer
    ' for clarity, check for equality and for nothingness removed '    
    return String.Compare(obj1.Name, obj2.Name)    
End Function

Esse código (pelo menos semelhante) chegou à produção com um dos meus clientes e foi usado em um retorno de chamada do Ajax frequentemente chamado. Sem manualmente em cache o .Name Propriedades, já em listas de tamanho médio de menos de meio milhão de objetos, o código de ligação tardia se tornou um fardo tão perceptível que acabou reduzindo todo o site. Foi difícil rastrear esse problema, mas isso é uma história para outra hora. Depois de consertar isso, o site recuperou 95% de suas respostas da CPU.

Então, a resposta para a pergunta de Hans "Você não tem problemas maiores para se preocupar" é simples: este é um grande problema (ou pode ser), esp. Para os programadores VB que ficaram muito descuidados em usar a ligação tardia.

Nesse caso em particular, e muitos como eles, o vb.net 2010 aparentemente não foi atualizado para introduzir a ligação tardia e, como tal, Object permanece mau para os desconhecerem e não deve ser comparado com dynamic.

PS: Os problemas de desempenho tardios são muito difíceis de rastrear, a menos que você tenha um bom perfil de desempenho e saiba como a ligação tardia é implementada internamente pelo compilador.

Outras dicas

Citando do O que há de novo artigo:

O Visual Basic 2010 foi atualizado para apoiar totalmente o DLR em seu Latebinder

Não posso ficar mais explícito do que isso. É o DLR que implementa o cache.

Boa pergunta. Acho que a resposta é "não", porque Este artigo Na revista MSDN, diz que o VB.NET foi alterado para apoiar o tempo de execução dinâmico da linguagem e descreve brevemente as alterações no tempo de execução, mas não menciona o cache.

Alguém sabe melhor?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top