Le coût de performances à l'aide de ref au lieu de retourner mêmes types?
Salut c'est quelque chose de vraiment me tracasse et je suis en espérant que quelqu'un a une réponse pour moi. J'ai lu à propos de ref
(et out
) et je suis en train de voir si je suis à ralentir mon code à l'aide de ref
s. Souvent je vais remplacer quelque chose comme:
int AddToInt(int original, int add){ return original+add; }
avec
void AddToInt(ref int original, int add){ original+=add; } //1st parameter gets the result
car à mes yeux ce
AddToInt(ref _value, _add);
est plus facile à lire ET le code de cette
_value = AddToInt(_value, _add);
Je sais précisément ce que je suis en train de faire sur le code à l'aide de ref
, plutôt que de retourner une valeur. Cependant, la performance est quelque chose que je prends très au sérieux, et, apparemment, de déférence et de nettoyage est beaucoup plus lent lorsque vous utilisez réf.
Ce que j'aimerais savoir, c'est pourquoi tous les post que j'ai lu dit il y a très peu d'endroits qui vous passent un ref
(je sais que les exemples sont quelque peu exagéré, mais j'espère que vous voyez l'idée), quand il me semble que le ref
exemple est plus petit, plus propre et plus exacte.
J'aimerais également savoir pourquoi ref
est vraiment plus lent que de retourner une valeur de type - pour moi, il me semble, si j'allais modifier la valeur de la fonction d'un lot avant de le retourner, qu'il serait plus rapide de la référence de la variable réelle pour le modifier, par opposition à une instance de cette variable, peu de temps avant, il est nettoyé de la mémoire.
Vous êtes à essayer de comprendre l'impact sur les performances? Demandez à un profiler, ne nous demandez pas!
Le premier cas est plus facile à lire parce que vous avez nommé votre méthode en conséquence. Quelque chose comme
_value = Add(_value, _add);
ou _value = SumOf(_value, _add);
est plus lisible pour moi.double possible de C# " ref " mot-clé, de la performance
Résultats de mon petit test
OriginalL'auteur user1044057 | 2011-11-13
Vous devez vous connecter pour publier un commentaire.
Les principaux temps que "ref" est utilisé dans le même sentance que la performance est au moment de discuter de certains très atypique cas, par exemple dans le XNA scénarios où le jeu "objets" sont très souvent représentées par des structures plutôt que des classes pour éviter les problèmes avec les GC (qui a un impact disproportionné sur XNA). Cela devient utile:
Dans tous les autres cas, "ref" est le plus souvent associée avec un autre effet secondaire, pas facilement exprimées dans la valeur de retour (pour exemple, voir le Moniteur.TryEnter).
Si vous n'avez pas à un tel scénario, le XNA/struct, et il n'est pas maladroit effet secondaire, alors il suffit d'utiliser la valeur de retour. En plus d'être plus typique (ce qui en soi n'a de valeur), il pourrait bien impliquer en passant moins de données (et l'int est plus petite qu'une ref sur x64 par exemple), et pourrait exiger moins de déférence.
Enfin, le retour approche est plus polyvalent; vous n'avez pas toujours envie de mettre à jour la source. Contraste:
Je pense que la dernière est la moins claire (avec les autres "ref" un ferment derrière lui) et réf utilisation est encore moins clair dans les langues où il n'est pas explicite (VB par exemple).
Un avantage important de ref, cependant, le référencement de votre exemple: si quelque chose est passé par référence à une méthode comme Ajouter, il peut être possible pour la méthode à exécuter la mise à jour en lock-free, non-blocage, atomique, thread-safe mode. Donc, si deux threads simultanément appeler un "Ajouter" de la méthode, comme dans le deuxième exemple, x aura dix ajouté. En revanche, si l'un ou les deux fils fait la mise à jour comme indiqué dans le premier exemple, un thread peut annuler la mise à jour effectuée par l'autre.
pour cela, il avait encore besoin d'utiliser Contrefil etc...
Gravel: "Ajouter" méthode pourrait le faire à l'interne. Bien sûr, cela ne ferait que d'avoir de la valeur si tout le code qui a manipulé la chose a besoin de tels soins utilisés Contrefil méthodes, mais si la chose en question est un type de données personnalisé, c'est une possibilité réaliste.
OriginalL'auteur Marc Gravell
Le but principal de l'utilisation du mot-clé ref est pour signifier que la valeur de la variable peut être modifiée par la fonction de son passé. Lorsque vous passez une variable par valeur, les mises à jour à partir de la fonction ne pas l'effet de l'original de la copie.
Son extrêmement utile (et plus rapide) pour les situations où vous souhaitez que plusieurs valeurs de retour et la construction d'une spéciale struct ou class pour les valeurs de retour serait exagéré. Par exemple,
C'est une question assez fondamentale modèle dans les langues qui ont sans restriction de l'utilisation de pointeurs. En c/c++, vous voyez souvent des primitives d'être passés par valeur avec des classes et des tableaux de pointeurs. C# est l'opposé donc, " ref " est à portée de main dans des situations comme ci-dessus.
Lorsque vous passez une variable que vous voulez mettre à jour dans une fonction par ref, 1 seule opération d'écriture est nécessaire pour vous donner le résultat. Lors du renvoi des valeurs toutefois, vous écrivez à une variable à l'intérieur de la fonction, le retourner, puis d'écrire de nouveau à la variable de destination. Selon les données, ce qui pourrait ajouter une surcharge inutile. De toute façon, ce sont les principales choses que j'ai généralement considérer avant d'utiliser le mot-clé ref.
Parfois ref est un peu plus rapide lorsqu'il est utilisé comme ce, en c#, mais pas assez pour l'utiliser comme un goto justification de la performance.
Voici ce que j'ai obtenu sur un enfant de 7 ans à la machine à l'aide du code ci-dessous en passant et mise à jour d'un 100k chaîne par référence et par valeur.
De sortie:
itérations: 10000000
byref: 165ms
byval: 417ms
lancez tous les résultats sont corrects, les actions ne sont pas les mêmes sur les deux fonctions. La seule fonction est de retour quelque chose, l'autre pas. Le mot-clé ref seul à la comparer avec la non ref mot-clé n'est pas plus rapide, mais presque la même, si ce n'est plus lente. Pour faire une mesure correcte de faire deux fonctions avec les mêmes actions et seul le
ref
doit changer...OriginalL'auteur drankin2112
Je suis d'accord avec Ondrej ici. À partir d'une vue stylistique, si vous commencez à passer le tout avec
ref
vous finira par travailler avec des devs qui veulent étrangler avec vous pour concevoir une API comme ça!Juste retour des choses de la méthode, de ne pas avoir 100% de vos méthodes de retour
void
. Ce que vous faites va conduire à de très impur code et pourrait confondre autres développeurs qui travaillent sur votre code. Faveur de la clarté sur les performances ici, car vous n'aurez pas gain de beaucoup de optomization de toute façon.cochez cette SORTE de poste: C# " ref " mot-clé, la performance
et cet article de Jon Skeet: http://www.yoda.arachsys.com/csharp/parameters.html
OriginalL'auteur Jason Evans
D'abord, ne pas la peine à savoir si l'utilisation
ref
est plus lent ou plus rapide. Il est prématuré d'optimisation. Dans 99.9999% des cas, vous ne serez pas dans une situation ce serait la cause d'une performance bottlenect.Deuxième, en retournant le résultat du calcul d'une valeur de retour par opposition à l'aide
ref
est préférée en raison de l'habitude "fonctionnel" la nature de la C-comme les langues. Il conduit à une meilleure chaînage de déclarations/appels.Et bien en fait je sais et de savoir comment le mesurer. Cependant, il ne fait aucun sens de perdre du temps parce que nous parlons de quelques cycles CPU " la différence par appel.
Je n'aime pas (travailler avec) devs qui utilisent toujours des performances que l'affaire principale au moment de choisir entre certains styles de codage/dessins/architectures en de NON performance des secteurs critiques. Il se passe beaucoup de choses.
Ouais. grand. Je viens ici à la recherche pour cette info parce que je affronter la perforamnce applications de négociation. Il y a des cas vous cherchez à passer à des structures pour prendre en charge la gc...
OriginalL'auteur Ondrej Tucny