2017-10-20 12 views
1

Dans mon code de base actuel, les instructions complexes if sont souvent remplacées par des appels de délégation. En raison de la structure du code, le même délégué sera appelé plusieurs fois au cours de l'application. Par exemple,Le C# JITter peut-il optimiser les appels de délégués répétés?

class ExampleClass 
{ 
    private delegate double ExampleDelegate(double x, double y); 
    private ExampleDelegate _exampleMethod; 
    private bool _condition1; 

    ... 

    public double ApiFunction(List<double> a, List<double> b, bool condition2) 
    { 
     if ((_condition1 && !condition2) || getCondition3()) 
     { 
      _exampleMethod = adder; 
     } 
     else 
     { 
      _exampleMethod = subtracter; 
     } 

     double finalResult = 0; 

     for (int i = 0; i < a.Count; i++) 
     { 
      finalResult += _exampleMethod(a[i], b[i]); 
     } 

     return finalResult; 
    } 

    private double adder(double a, double b) 
    { 
     return a + b; 
    } 

    private double subtracter(double a, double b) 
    { 
     return a - b; 
    } 
} 

Puisque la performance est une préoccupation ici, je me demande si le JITter finira par se rendre compte que l'une de ces méthodes est appelé à chaque fois et en ligne ou autrement optimiser l'appel.

Alors, le C JITter peut-il aligner ou optimiser les appels délégués multiples?

+0

Que diriez-vous de l'évaluer pour voir quel genre de surdéclaré votre répartition par délégué a? Aussi, afaik utilisant des groupes de méthodes est plus cher que d'utiliser des expressions lambda, donc je suggère d'essayer '_exampleMethod = (a, b) => additionneur (a, b);'. Mais encore une fois, vous êtes curieux de savoir perf? Référence! – MarcinJuraszek

+0

@MarcinJuraszek En ce qui concerne votre remarque sur les lambdas, les méthodes actuelles sont beaucoup plus compliquées, généralement autour de 25 lignes. Je ferai peut-être quelques benchmarks de performances pour voir l'impact réel sur les performances plus tard, mais je m'intéresse également à ce qui se passe techniquement en coulisses, pas seulement à l'impact réel sur les performances. Merci. – Defenestrator

+0

@MarcinJuraszek Pourquoi croyez-vous que la création d'une nouvelle méthode qui ne fait qu'appeler une autre méthode, en transmettant exactement les mêmes paramètres et en ne faisant aucun travail productif serait plus efficace? – Servy

Répondre

4

Ce n'est pas le cas. Les appels délégués sont toujours des appels indirects et liés dynamiquement au moment de l'exécution. Cela arrive au moment où l'appel est fait, seulement alors la valeur de l'objet délégué est connue. La gigue s'exécute avant cela, il n'y a rien que l'optimiseur puisse faire pour les améliorer, il n'a aucune connaissance de ce qui va être appelé.

Notez comment il ne peut pas savoir si la méthode cible est une méthode d'instance ou statique, elle suppose une méthode d'instance. Le travail supplémentaire doit être effectué par le talon d'appel s'il est statique pour réactiver la pile d'appels. Ce travail supplémentaire est plus important pour le code x64. Notable dans l'extrait est qu'une méthode statique aurait normalement plus de sens alors méfiez-vous de cela.

Le premier appel coûte cher, c'est-à-dire que le talon d'appel est créé et que la méthode cible doit être envoyée. Puisque dans ce cas la gigue aura déjà deviné correctement à quoi ressemble la méthode, le stub est simplement une simple instruction JMP. Tout appel effectué après cela a une vitesse normale et, au-delà du JMP, il ne sera pas sensiblement plus lent qu'un appel normal, bien que vous ne puissiez pas bénéficier de l'inlining comme le feraient normalement ces petites méthodes. Aucun changement n'est fait, .NET n'a rien à voir avec un compilateur de hotspot car il n'utilise pas d'interpréteur.

Vous devrez mesurer, sachez qu'il s'agit d'un code très rapide, donc les erreurs de benchmarks simples ont tendance à faire mal et les mesures ne seront pas très cohérentes. Mais pensez à y consacrer du temps seulement lorsque vous découvrez que vous avez un problème de performance réel. Ce n'est pas commun, les délégués ne craignent pas.