2010-05-16 2 views
6

J'ai une méthode en C# qui doit renvoyer un très grand tableau (ou toute autre structure de données volumineuse d'ailleurs).Fonction C# valeur de retour normale VS argument out ou ref

Y a-t-il un gain de performance dans l'utilisation d'un paramètre ref ou out au lieu de la valeur de retour standard?

I.E. est-il un rendement ou un autre gain en utilisant

void function(sometype input, ref largearray) 

sur

largearray function(sometype input) 
+0

Je pense que vous êtes confus; vous retourneriez une référence à un grand tableau, pas au tableau lui-même ... –

+1

Les tableaux Stadard .Net sont déjà des types de référence. – Dykam

Répondre

5

La quantité d'espace de pile utilisé sur un processeur x86 32 bits pour transmettre des arguments de divers types:

  • octet: 4 octets
  • bool: 4 octets
  • enum: 4 octets
  • Char: 4 octets
  • court: 4 octets
  • int: 4 octets
  • longue: 8 b YTES
  • float: 4 octets
  • double: 8 octets
  • décimal: 16 octets
  • struct: Taille de l'exécution de la structure

    chaîne
  • : 4 octets
  • tableau: 4 octets
  • objet: 4 octets
  • Interface: 4 octets
  • pointeur
  • : 4 octets
  • instance de classe: 4 octets

ceux ci-dessous de la ligne sont des types de référence, leur taille va doubler sur un processeur 64 bits.

Pour un appel de méthode statique, les 2 premiers arguments de 4 octets au maximum seront transmis via les registres de la CPU, et non la pile. Pour un appel de méthode d'instance, un seul argument sera passé dans les registres. Le reste est passé sur la pile. Un processeur 64 bits prend en charge le passage de 4 arguments à travers des registres.

Comme il ressort de la liste, la seule fois où vous devriez envisager de passer un argument par ref est pour les structures. Le conseil normal pour cela est de le faire lorsque la structure est supérieure à 16 octets. Il n'est pas toujours facile de deviner la taille d'exécution d'une structure, jusqu'à 4 champs sont généralement précis. Moins si ces champs sont doubles, longs ou décimaux. Ce guide recommande alors généralement de transformer votre structure en classe, précisément pour cette raison. Notez également qu'il existe aucune économie en passant un argument comme un octet ou court intentionnellement, un int est le type dont un processeur 32 bits est content. Idem pour les processeurs 64 bits actuellement disponibles. Une valeur de retour de méthode, le vrai sujet de votre question sont presque toujours retournés dans un registre CPU. La plupart des types s'adaptent confortablement dans les registres eax ou edx: eax, un registre FPU pour les valeurs à virgule flottante. Les seules exceptions sont les grandes structures et les décimales, elles sont trop grandes pour s'adapter à un registre. Ils sont appelés en réservant de l'espace sur la pile pour la valeur de retour et en passant un pointeur de 4 octets à cet espace en tant qu'argument de la méthode.

+0

C'est la réponse que je cherche.Je ne peux pas voir comment signaler ceci comme réponse cependant - je suis un débutant et j'ai un peu aveuglé peut-être? – user335023

1

Un paramètre out renvoie une référence à une instance de type, qui n'a pas besoin d'être initialisée avant de l'envoyer dans un procédé.

Un paramètre ref renvoie une référence à une instance de type, qui doit être initialisé avant de l'envoyer dans un procédé.

Ceci concerne la sémantique d'appel, PAS les performances.

1

Il n'y a pas, juste retourner le tableau

1

Il n'y aurait pas de différence entre

void function(sometype input, out largearray output) 

sur

largearray function(sometype input) 

Cependant, si vous

largearray function(sometype input, ref largearray output) 

et vous avez besoin Si l'appelant avait pré-alloué le grand tableau, ce serait bien sûr plus rapide, mais cela n'aurait d'importance que si vous appeliez la méthode plusieurs fois et que vous conserviez le grand tableau alloué entre les appels.

Questions connexes