2010-03-05 1 views
15

Cette blog ditL'ajout d'instructions de retour pour les méthodes C# améliore-t-il les performances?

12) comprennent des énoncés de retour avec dans la fonction/méthode. Comment cela améliore les performances L'utilisation explicite du retour permet au JIT d'effectuer légèrement plus d'optimisations. Sans déclaration de retour, chaque variable de la fonction/pile reçoit plusieurs variables locales pour supporter de manière transparente les valeurs renvoyées sans le mot-clé. En les conservant, il est plus difficile pour le JIT d'optimiser et de réduire les performances de votre code. Regardez à travers vos fonctions/méthodes et insérez le retour au besoin. Cela ne change rien à la sémantique du code, et cela peut vous aider à tirer le meilleur parti de votre application. Je suis à peu près sûr qu'il s'agit d'une fausse déclaration.

Mais je voulais faire venir les experts d'opinion là-bas. Qu'en pensez-vous?

+4

Semble poisson, en effet, mais je vais laisser le poids des gourous JIT! – mjv

+4

Il y a plus d'instructions fishy. "Use 'ArrayLists' à la place des tableaux", "Design with ValueTypes". Je veux dire, ArrayLists? C'est super avec la boxe. Et savoir exactement quand utiliser des structures au lieu de classes est quelque chose de très, sinon la plupart des gens se mélangent - y compris moi. Étrange "astuce". – Razzie

+0

Dans la lignée de la remarque de @ Razzie, je prendrais ce post avec un grain de sel, il ne prend pas en considération les éléments ajoutés même dans les jours .NET 2.0 .... –

Répondre

10

Cette instruction ne s'applique pas à C#. Avec C#, vous devez explicitement définir un "retour" pour avoir une fonction valide, sans retour, vous obtenez une erreur de compilation avec l'effet "tous les chemins de code ne renvoient pas une valeur". Avec VB.NET, cela s'appliquerait car VB.NET n'a pas besoin d'un retour explicite, et vous permet d'avoir des fonctions qui ne renvoient jamais de valeur, ainsi que de vous permettre de définir le retour en utilisant le nom de VB.NET. la fonction.

Pour donner un exemple

En VB.NET, vous pouvez le faire

Function myFunction() As String 
    myFunction = "MyValue" 
End Function 

Function myFunction2() As String 
    'Your code here 
End Function 

Les compiles ci-dessus, ni avec un « rendement » explicites, il y a plus de frais généraux impliqués dans ce domaine.

Si vous essayez de le faire avec C#

string myFunction() 
{ 
    //Error due to "Cannot assign to 'myFunction' because it is a 'Method Group' 
    myFunction = "test"; 
} 

string myFunction2() 
{ 
    //Error due to "not all code paths return a value 
} 

Mes commentaires notent les erreurs que vous obtenez.

+0

... personnellement? – Svish

+0

Ouais, enlevé cela .... c'était une longue matinée déjà ... –

+0

J'ai lu le texte cité du PO du blog comme signifiant en utilisant des déclarations de retour au traitement de court-circuit comme dans la conjecture de Nick. – chsh

1

Ma seule supposition ici est qu'il parle de VB.NET pas C#. VB.NET vous permet de Somethin comme celui-ci pour renvoyer des valeurs

Public Function GetSomething() As Int 
    GetSomething = 4 
End Function 

Mon VB est incroyablement à jour cependant. Cela peut être plus lent qu'en utilisant une déclaration de retour explicite.

+0

En outre ce post: http://stackoverflow.com/questions/451025/vb-net-function-return parler de la performance et la déclaration de retour dans VB.Net: Le il généré semble presque le même ergo la vitesse est la même. (Je n'ai pas fait de démontage moi-même mais celui présenté dans cette question semble logique) –

+0

@dotjoe: Comment ça? C'est en fait très utile pour les cas où vous devriez, en C#, déclarer une variable 'result' (ou similaire). Personnellement, j'ai entièrement adapté le style C#, mais je ne peux pas former un argument convaincant pourquoi le style VB devrait être pire. Pour moi, c'est simplement une question d'habitude, et la façon de faire de VB est parfaitement raisonnable. –

+0

@Konrad Rudolph wait ... cette syntaxe n'est pas la même que 'Return 4'? Est-ce qu'il détient le résultat jusqu'à la fin de la fonction et peut être réglé plusieurs fois? – dotjoe

4

Le message est plutôt vague. Être un développeur C#, ma première pensée était "par opposition à quoi?". Cependant, il pourrait se référer à quelque chose comme:

public bool MyFunction() 
{ 
    bool result = false; 
    if (someCondition == true) 
    { 
     // Do some processing 
     result = true; 
    } 
    else if (someOtherCondition == true) 
    { 
     // Do some processing 
     result = true; 
    } 
    // ... keep going 

    return result; 
} 

Il peut suggérer que le remplacement des déclarations result = true; avec return true; peut effectuer mieux. Je ne suis pas sûr à ce sujet personnellement ... c'est assez profond dans la théorie de JIT à ce moment-là, et je pense que tous les gains qui sont faits seraient très mineurs comparés à d'autres améliorations de performance que vous pourriez faire.

+0

D'accord avec cela - c'est l'un de ces moments où vous devez décider que la maintenabilité est plus importante que le gain de performance insignifiant! – Fenton

0

Généralement il y a 2 points dans lesquels je quitte une fonction. Au début de mes méthodes pour valider les données entrantes:

if (myParameter == null) 
    throw new ArgumentNullException("myParameter"); 

et/ou à la fin de la méthode.


private bool GetSomeValue() 
{ 
    bool returnValue = false; 
    // some code here 
    if (some condition) 
    { 
     returnValue = some expression 
    } 
    else 
    { 
     returnValue = some other expression; 
    } 
    return returnValue; 
}

La raison pour laquelle je ne retourne pas à l'intérieur du conditionnel, est donc qu'il ya 1 point de sortie de la fonction, il aide à la mise au point. Personne ne veut avoir à maintenir une méthode avec 12 déclarations de retour. Mais ce n'est qu'une opinion personnelle. J'opterais pour la lisibilité, et je ne m'inquiéterais pas de l'optimisation, à moins que vous n'ayez à faire face à une situation d'urgence.

+4

IMO la notion de point de retour unique n'est pas pertinente dans les logiciels modernes. Je préfère voir immédiatement une déclaration de retour et savoir que le code est sorti que de devoir se demander si returnValue est manipulé ailleurs plus bas dans la méthode si vous pouviez revenir de l'intérieur de ces blocs if. –

+1

@ChrisMarisic - Je suis d'accord. L'argument multiple-returns-is-bad ajoute * noise * au code. Si vous devez revenir à 5 endroits, cela ne peut pas être pire que de se ramifier de 5 façons à la fin avec l'état de changement possible avec le lecteur possible ne pas suivre l'intention. – Kit

+0

@Kit J'ai dû lire votre commentaire quelques fois pour m'assurer que je l'ai compris. Je suis d'accord avec vous, choisissant de retarder le retour quand vous pouvez revenir immédiatement ** sera ** ajouter du bruit au code. –

2

C'est un peu vrai, à la fois pour VB.NET et C#. En C# le programmeur doit déclarer explicitement la variable qui contient la valeur de retour, elle est automatique dans VB.NET. La plupart des valeurs de retour sont retournées dans le registre EAX ou RAX, le compilateur JIT doit générer du code pour charger le registre à partir de la variable de valeur de retour avant que la fonction ne quitte. Lorsque vous utilisez l'instruction return, le compilateur JIT peut avoir la possibilité de charger le registre EAX directement, ou déjà avoir le registre contenant la valeur correcte, et passer au code de sortie de fonction, en contournant l'instruction load-from-variable.

C'est un très gros "pourrait" btw, le vrai code teste invariablement une expression avec l'instruction if(). L'évaluation de cette expression implique presque toujours l'utilisation du registre EAX, il doit encore être rechargé avec la valeur de retour. Le compilateur JIT x64 fait un travail complètement différent par rapport au compilateur x86, ce dernier semble toujours utiliser la variable dans quelques vérifications ponctuelles que j'ai faites. Il est donc peu probable que vous soyez en avance si vous n'utilisez pas une version 64 bits de Windows.

De tout le mal en optimisation prématurée, celui-ci est sans doute le pire. Les économies de temps potentielles sont minuscules, écrivez votre code pour plus de clarté en premier. Profil plus tard.

+0

Il y a un cas que la syntaxe de retour simplifie pour le compilateur c'est l'optimisation de récurrence d'appel de queue car il est légèrement plus facile à faire quand l'appel de retour est ici car il n'y a pas besoin de suivre le code -recursive ou non (recherchez simplement les sauts à la fin du corps de la méthode). Mais je ne connais pas l'état actuel du compilateur JIT en ce qui concerne ce cas particulier, donc il peut même ne pas être un problème. –

+0

Les petits détails sales !!! Voilà de quoi je parle .. Merci nobugz :) – HashName

3

Je ne suis pas d'accord - Je pense qu'un simple et unique de chaque méthode rend le code beaucoup plus facile à lire et à déboguer. Plusieurs déclarations de retour dans une fonction peuvent rendre le code de navigation plus comlpex. En fait (si possible de refactoriser) il est préférable d'avoir des fonctions plus petites que de dire des fonctions plus grandes avec plusieurs sorties.

Questions connexes