Question

Certaines personnes ont fait valoir que la fonction C # 4.0 introduit avec le mot-clé dynamic est la même que la fonction « tout est un objet » de VB. Cependant, tout appel à une variable dynamique sera traduite en un délégué une fois et à partir de là, sera appelé le délégué. En VB, lors de l'utilisation Object, aucune mise en cache est appliqué et chaque appel sur une méthode non typé implique beaucoup de sous le capot de réflexion, totalisant parfois une somme exorbitante de 400 fois les performances.

Avez type dynamique délégué-optimisation et la mise en cache également été ajoutés aux appels de méthode VB typées, ou est VB typées de l'objet encore si lent?

Était-ce utile?

La solution

Solution

Des recherches et une meilleure lecture du antérieure visée à l'article mentionné par Hans Passant, entraîne la conclusion suivante:

  • VB.NET 2010 prend en charge le DLR;
  • Vous pouvez mettre en œuvre IDynamicMetaObjectProvider si vous voulez soutenir explicitement la dynamique, le compilateur VB.NET est mis à jour pour reconnaître que,
  • Le Object VB utilisera uniquement le DLR et la mise en cache de méthode si les outils d'objet IDynamicMetaObjectProvider;
  • BCL et types cadres ne mettent pas en œuvre IDynamicMetaObjectProvider, en utilisant Object sur ces types ou vos propres types invoquera l'VB.NET classique, non-cache en fin de liant.

Contexte: élaboration pourquoi la mise en cache liaison tardive pourrait aider VB performance du code

Certaines personnes (parmi lesquels Hans Passant, voir sa réponse) peut se demander pourquoi la mise en cache ou non-mise en cache dans la liaison tardive pourrait peut-être la matière. En fait, cela fait une grande différence, tant en VB et dans d'autres technologies liaison tardive (souvenez-vous IQueryInterface avec COM?).

liaison tardive se résume à un principe simple: donner un nom et ses paramètres-déclarations, boucle à travers toutes les méthodes de cette classe et ses classes parentes au moyen de méthodes disponibles si l'interface Type (et en VB, une méthode , une propriété et un champ peuvent voir même, ce qui rend ce processus encore plus lent). Si l'on considère que les tables de méthode ne sont pas ordonnés, cela est facilement beaucoup plus cher qu'un seul appel de méthode directe (à savoir tapé).

Si vous étiez capable de regarder la méthode une fois, puis le stockage de la méthode pointeur dans une table de consultation, ce serait grandement accélérer ce processus. méthode de liaison dans le cache DLR va un futher étape et remplace la méthode d'appel avec un pointeur vers la méthode réelle, si possible. Après le premier appel, cela devient un ordre de grandeur plus rapide pour chaque appel suivant (pensez 200x à 800x fois plus rapide).

À titre d'exemple lorsque cette question est importante, voici un code qui illustre cette question. Dans le cas où chaque classe possède une propriété chaîne de .Name, mais les classes ne partagent un ancêtre commun ou de l'interface, vous pouvez trier les listes de naïvement l'un de ces types comme ceci:

' 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

Ce code (similaire au moins) en fait en production avec un de mes clients et a été utilisé dans un rappel AJAX souvent appelé. Sans la mise en cache manuellement les propriétés de .Name, déjà sur les listes de taille moyenne de moins d'un demi-million d'objets, le code de liaison tardive est devenu un fardeau notable qu'il a finalement amené l'ensemble du site vers le bas. Il a prouvé difficile de traquer cette question, mais c'est une histoire pour une autre fois. Après avoir fixé cela, le site a retrouvé 95% de ses resouces CPU.

Alors, la réponse à la question de Hans « ne pas que vous avez des problèmes plus graves à se soucier » est simple: cela est un gros problème (ou peut être), esp. aux programmeurs VB qui ont obtenu trop négligents sur l'utilisation de la liaison tardive.

Dans ce cas particulier, et beaucoup comme eux, VB.NET 2010 n'a apparemment pas été mis à jour pour introduire la liaison tardive, et en tant que telle, Object reste mal pour l'ignorer et ne doit pas être comparé à dynamic.

PS:. Liaison tardive des problèmes de performance sont très difficiles à trouver, sauf si vous avez une bonne performance profileur et savoir-liaison tardive est mis en œuvre en interne par le compilateur

Autres conseils

Je cite nouveautés article :

  

Visual Basic 2010 a été mis à jour   soutenir pleinement le DLR dans son   latebinder

Ne peut pas obtenir plus explicite que cela. Il est le DLR qui implémente la mise en cache.

Bonne question. Je devine que la réponse est « Non », parce que cet article dans le magazine MSDN dit VB.Net a été modifié pour soutenir le Dynamic Language Runtime, et décrit brièvement les modifications à l'exécution, mais ne mentionne pas la mise en cache.

Quelqu'un sait-il mieux?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top