307 votes

Fonctions en ligne en C# ?

Comment faire des "fonctions en ligne" en C# ? Je ne pense pas avoir compris le concept. Sont-elles comme des méthodes anonymes ? Comme les fonctions lambda ?

Note : Les réponses portent presque entièrement sur la capacité à fonctions en ligne c'est-à-dire "une optimisation manuelle ou du compilateur qui remplace le site d'appel d'une fonction par le corps de l'appelé". Si vous êtes intéressé par fonctions anonymes (alias lambda) voir La réponse de @jalf o Qu'est-ce que ce "Lambda" dont tout le monde parle ? .

13 votes

C'est enfin possible - voir ma réponse.

1 votes

Pour les curieux, Vérifiez cette extension VS .

436voto

konrad.kruczynski Points 5938

Enfin, dans .NET 4.5, le CLR permet d'indiquer/suggérer 1 en utilisant la méthode inlining MethodImplOptions.AggressiveInlining valeur. Il est également disponible dans le tronc de Mono (commit aujourd'hui).

// The full attribute usage is in mscorlib.dll,
// so should not need to include extra references
using System.Runtime.CompilerServices; 

...

[MethodImpl(MethodImplOptions.AggressiveInlining)]
void MyMethod(...)

1 . Auparavant, le terme "force" était utilisé ici. Je vais essayer de clarifier ce terme. Comme dans les commentaires et la documentation, The method should be inlined if possible. En particulier, si l'on considère Mono (qui est ouvert), il existe certaines limitations techniques spécifiques à Mono, comme l'inlining ou des limitations plus générales (comme les fonctions virtuelles). Dans l'ensemble, oui, c'est une indication pour le compilateur, mais je suppose que c'est ce qui a été demandé.

1 votes

C'est vraiment utile pour les auteurs de compilateurs :)

18 votes

+1 - Mise à jour de votre réponse pour être plus spécifique sur les exigences de la version du framework.

4 votes

Ce n'est probablement pas encore force en ligne, mais remplacer l'heuristique des JITters est certainement suffisant dans la plupart des situations.

91voto

Cody Brocious Points 24042

Les méthodes en ligne sont simplement une optimisation du compilateur où le code d'une fonction est intégré à l'appelant.

Il n'y a pas de mécanisme permettant de faire cela en C#, et ils doivent être utilisés avec parcimonie dans les langages où ils sont supportés -- si vous ne savez pas pourquoi ils devraient être utilisés quelque part, ils ne devraient pas l'être.

Edit : Pour clarifier, il y a deux raisons majeures pour lesquelles ils doivent être utilisés avec parcimonie :

  1. Il est facile de faire des binaires massifs en utilisant l'inline dans les cas où ce n'est pas nécessaire.
  2. Le compilateur a tendance à savoir mieux que vous quand quelque chose doit, du point de vue des performances, être inlined.

Il est préférable de ne rien faire et de laisser le compilateur faire son travail, puis d'établir un profil et de déterminer si la mise en ligne est la meilleure solution pour vous. Bien sûr, certaines choses ont tout simplement du sens d'être inline (les opérateurs mathématiques en particulier), mais laisser le compilateur s'en occuper est généralement la meilleure pratique.

40 votes

Normalement, je pense que c'est bien que le compilateur gère l'inlining. Mais il y a des situations où j'aime passer outre la décision du compilateur et mettre en ligne ou non une méthode.

0 votes

Rstevens, je suis d'accord, mais à moins que vous ayez une bonne raison /de/ mettre quelque chose en ligne, je pense que la meilleure pratique est de laisser le compilateur s'en occuper et de le modifier plus tard si le profilage montre que c'est un problème.

0 votes

@rstevens : Vous pouvez toujours choisir de forcer une fonction inline en déplaçant l'implémentation physique de callee vers l'appelant. L'inverse, bien sûr, n'est pas si simple

64voto

BACON Points 2766

Mise à jour: Par konrad.kruczynski, en réponse, la suivante est vraie pour les versions de .NET jusqu'à et y compris 4.0.

Vous pouvez utiliser le MethodImplAttribute classe pour empêcher une méthode de inline...

[MethodImpl(MethodImplOptions.NoInlining)]
void SomeMethod()
{
    // ...
}

...mais il n'y a aucun moyen de faire le contraire et à force d'être insérée.

2 votes

C'est intéressant de le savoir, mais pourquoi diable empêcher une méthode d'être inlined ? J'ai passé un certain temps à regarder l'écran mais je n'arrive pas à trouver une raison pour laquelle l'inlining pourrait faire du tort.

3 votes

Si vous recevez une pile d'appels (c'est-à-dire une NullReferenceException) et qu'il est évident qu'il est impossible que la méthode située au sommet de la pile l'ait lancée. Bien sûr, l'un de ses appels peut l'avoir fait. Mais lequel ?

20 votes

GetExecutingAssembly y GetCallingAssembly peut donner des résultats différents selon que la méthode est inlined ou non. Le fait de forcer une méthode à ne pas être inlined élimine toute incertitude.

38voto

jalf Points 142628

Vous mélangez deux concepts distincts. L'inlining des fonctions est une optimisation du compilateur qui n'a aucun impact sur la sémantique. Une fonction se comporte de la même manière, qu'elle soit inlined ou non.

En revanche, les fonctions lambda sont un concept purement sémantique. Il n'y a aucune exigence sur la façon dont elles doivent être mises en œuvre ou exécutées, tant qu'elles suivent le comportement défini dans la spécification du langage. Elles peuvent être inlined si le compilateur JIT le souhaite, ou non si ce n'est pas le cas.

Il n'y a pas de mot-clé inline en C#, car il s'agit d'une optimisation qui peut généralement être laissée au compilateur, en particulier dans les langages JIT. Le compilateur JIT a accès à des statistiques d'exécution qui lui permettent de décider ce qu'il faut mettre en ligne de manière beaucoup plus efficace que vous ne pouvez le faire en écrivant le code. Une fonction sera inline si le compilateur le décide, et vous ne pouvez rien y faire de toute façon :)

22 votes

"Une fonction se comporte de la même manière qu'elle soit inlined ou non." Il y a quelques rares cas où ce n'est pas vrai : notamment les fonctions de journalisation qui veulent connaître la trace de la pile. Mais je ne veux pas trop affaiblir votre affirmation de base : c'est un fait. généralement vrai.

1 votes

" et il n'y a rien que vous puissiez faire de toute façon. " - ce n'est pas vrai. Même si nous ne comptons pas la "forte suggestion" au compilateur comme faisant quelque chose, vous pouvez empêcher les fonctions d'être inlined.

22voto

JaredPar Points 333733

Voulez-vous dire les fonctions en ligne dans le sens de C++ ? Dans lequel le contenu d'une fonction normale est automatiquement copié en ligne dans le site d'appel ? L'effet final étant qu'aucun appel de fonction ne se produit réellement lors de l'appel d'une fonction.

Exemple :

inline int Add(int left, int right) { return left + right; }

Si c'est le cas, alors non, il n'y a pas d'équivalent en C#.

Ou bien voulez-vous dire les fonctions qui sont déclarées dans une autre fonction ? Si c'est le cas, alors oui, C# supporte cela via des méthodes anonymes ou des expressions lambda.

Exemple :

static void Example() {
  Func<int,int,int> add = (x,y) => x + y;
  var result = add(4,6);  // 10
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X