Comment faites-vous des "fonctions en ligne" en C #? Je ne pense pas comprendre le concept. Sont-ils comme des méthodes anonymes? Comme les fonctions lambda?
Remarque : Les réponses traitent presque entièrement de la capacité à incorporer des fonctions , c'est-à-dire "une optimisation manuelle ou de compilation qui remplace un site d'appel de fonction par le corps de l'appelé". Si vous êtes intéressé par les fonctions anonymes (aka lambda) , voir la réponse de @ jalf ou de quoi parle cette 'Lambda' dont tout le monde parle? .
c#
optimization
inline
Dinah
la source
la source
Réponses:
Enfin dans .NET 4.5, le CLR permet de suggérer / suggérer 1 méthode en ligne en utilisant la
MethodImplOptions.AggressiveInlining
valeur. Il est également disponible dans le coffre du Mono (engagé aujourd'hui).1 . Auparavant, la «force» était utilisée ici. Puisqu'il y a eu quelques downvotes, je vais essayer de clarifier le terme. Comme dans les commentaires et la documentation, en
The method should be inlined if possible.
particulier en ce qui concerne Mono (qui est ouvert), il existe certaines limitations techniques spécifiques à mono en ce qui concerne l'inclusion ou plus générale (comme les fonctions virtuelles). Dans l'ensemble, oui, c'est un indice pour le compilateur, mais je suppose que c'est ce qui a été demandé.la source
Les méthodes en ligne sont simplement une optimisation du compilateur où le code d'une fonction est roulé dans l'appelant.
Il n'y a pas de mécanisme pour le faire en C #, et ils doivent être utilisés avec parcimonie dans les langages où ils sont pris en charge - 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 principales pour lesquelles ils doivent être utilisés avec parcimonie:
Il est préférable de laisser les choses tranquilles et de laisser le compilateur faire son travail, puis de profiler et de déterminer si l'inline est la meilleure solution pour vous. Bien sûr, certaines choses ont simplement du sens d'être intégrées (opérateurs mathématiques en particulier), mais laisser le compilateur gérer cela est généralement la meilleure pratique.
la source
Mise à jour: Par la réponse de konrad.kruczynski , ce qui suit est vrai pour les versions de .NET jusques et y compris 4,0.
Vous pouvez utiliser la classe MethodImplAttribute pour empêcher une méthode d'être en ligne ...
... mais il n'y a aucun moyen de faire le contraire et de le forcer à être aligné.
la source
GetExecutingAssembly
etGetCallingAssembly
peut donner des résultats différents selon que la méthode est en ligne ou non. Forcer une méthode à ne pas être alignée élimine toute incertitude.Vous mélangez deux concepts distincts. L'insertion de fonction 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 intégrée ou non.
En revanche, les fonctions lambda sont purement un concept sémantique. Il n'y a aucune exigence sur la façon dont ils doivent être implémentés ou exécutés, tant qu'ils suivent le comportement défini dans la spécification de langue. Ils peuvent être insérés si le compilateur JIT le souhaite, ou non si ce n'est pas le cas.
Il n'y a pas de mot clé en ligne en C #, car c'est 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 quoi incorporer beaucoup plus efficacement que lors de l'écriture du code. Une fonction sera insérée si le compilateur décide de le faire, et vous ne pouvez rien y faire de toute façon. :)
la source
Voulez-vous dire les fonctions en ligne au sens 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:
Si c'est le cas, non, il n'y a pas d'équivalent C # à cela.
Ou voulez-vous dire des fonctions qui sont déclarées dans une autre fonction? Si c'est le cas, alors oui, C # le prend en charge via des méthodes anonymes ou des expressions lambda.
Exemple:
la source
Cody a raison, mais je veux donner un exemple de ce qu'est une fonction en ligne.
Disons que vous avez ce code:
L' optimiseur du
compilateurJust-In-Time pourrait choisir de modifier le code pour éviter de placer à plusieurs reprises un appel à OutputItem () sur la pile, de sorte que ce serait comme si vous aviez écrit le code comme ceci à la place:Dans ce cas, nous dirions que la fonction OutputItem () a été insérée. Notez qu'il peut le faire même si OutputItem () est également appelé depuis d'autres endroits.
Modifié pour montrer un scénario plus susceptible d'être intégré.
la source
Oui Exactement, la seule distinction est le fait qu'il renvoie une valeur.
Simplification (sans utiliser d'expressions):
List<T>.ForEach
Prend une action, il ne s'attend pas à un résultat de retour.Donc, un
Action<T>
délégué suffirait .. dire:revient à dire:
la différence est que le type de param et la decleration de délégué sont inférés par l'utilisation et les accolades ne sont pas requises sur une méthode en ligne simple.
Tandis que
List<T>.Where
Prend une fonction, attend un résultat.On
Function<T, bool>
attendrait donc un :ce qui équivaut à:
Vous pouvez également déclarer ces méthodes en ligne et les affecter aux variables IE:
ou
J'espère que ça aide.
la source
Il y a des occasions où je souhaite forcer le code à être aligné.
Par exemple, si j'ai une routine complexe où il y a un grand nombre de décisions prises dans un bloc hautement itératif et ces décisions entraînent des actions similaires mais légèrement différentes à mener. Considérons, par exemple, un comparateur de tri complexe (non piloté par une base de données) où l'algorithme de tri trie les éléments selon un certain nombre de critères différents, comme on pourrait le faire s'ils triaient des mots selon des critères grammaticaux et sémantiques pour un langage rapide système de reconnaissance. J'aurais tendance à écrire des fonctions d'aide pour gérer ces actions afin de maintenir la lisibilité et la modularité du code source.
Je sais que ces fonctions d'aide devraient être intégrées car c'est ainsi que le code serait écrit s'il n'avait jamais été compris par un humain. Je voudrais certainement m'assurer dans ce cas qu'il n'y avait pas de fonction appelant les frais généraux.
la source
L'énoncé "il vaut mieux laisser ces choses tranquilles et laisser le compilateur faire le travail .." (Cody Brocious) est complètement délabré. Je programme du code de jeu hautes performances depuis 20 ans, et je n'ai pas encore trouvé de compilateur suffisamment «intelligent» pour savoir quel code doit être intégré (fonctions) ou non. Il serait utile d'avoir une instruction "inline" en c #, la vérité est que le compilateur n'a tout simplement pas toutes les informations dont il a besoin pour déterminer quelle fonction doit toujours être en ligne ou non sans l'indication "en ligne". Bien sûr, si la fonction est petite (accesseur), elle peut être automatiquement intégrée, mais que se passe-t-il s'il s'agit de quelques lignes de code? Nonesense, le compilateur n'a aucun moyen de savoir, vous ne pouvez pas laisser cela au compilateur pour un code optimisé (au-delà des algorithmes).
la source
Je sais que cette question concerne C #. Cependant, vous pouvez écrire des fonctions en ligne dans .NET avec F #. voir: Utilisation de `inline` en F #
la source
Non, il n'y a pas une telle construction en C #, mais le compilateur .NET JIT pourrait décider de faire des appels de fonction en ligne à l'heure JIT. Mais je ne sais pas vraiment s'il fait vraiment de telles optimisations.
(Je pense que ça devrait :-))
la source
Dans le cas où vos assemblys seront ngen-ed, vous voudrez peut-être jeter un œil à TargetedPatchingOptOut. Cela aidera ngen à décider si les méthodes doivent être intégrées. Référence MSDN
Cependant, ce n'est qu'une indication déclarative à optimiser, pas une commande impérative.
la source
Les expressions lambda sont des fonctions en ligne! Je pense que C # n'a pas d'attribut supplémentaire comme inline ou quelque chose comme ça!
la source
C # ne prend pas en charge les méthodes (ou fonctions) en ligne comme le font les langages dynamiques comme python. Cependant, les méthodes anonymes et les lambdas peuvent être utilisés à des fins similaires, y compris lorsque vous devez accéder à une variable dans la méthode conteneur comme dans l'exemple ci-dessous.
la source