[C#] Fonctions en ligne en C #?


Answers

Les méthodes en ligne sont simplement une optimisation de compilateur où le code d'une fonction est roulé dans l'appelant.

Il n'y a aucun mécanisme permettant de faire cela en C #, et ils doivent être utilisés avec parcimonie dans des 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 principales pour lesquelles ils doivent être utilisés avec parcimonie:

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

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

Question

Comment faites-vous les "fonctions en ligne" en C #? Je ne pense pas comprendre le concept. Sont-ils comme des méthodes anonymes? Comme les fonctions lambda?

Note : Les réponses traitent presque entièrement de la capacité à intégrer des fonctions , c.-à-d. «Une optimisation manuelle ou du compilateur 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) , consultez la réponse de @ jalf ou Qu'est-ce que c'est "Lambda" dont tout le monde parle? .




Vous mélangez deux concepts distincts. La fonction inline est une optimisation de compilateur qui n'a aucun impact sur la sémantique. Une fonction se comporte de la même manière qu'elle soit en ligne ou non.

D'un autre côté, les fonctions lambda sont purement un concept sémantique. Il n'y a aucune exigence sur la façon dont ils devraient être mis en œuvre ou exécutés, tant qu'ils suivent le comportement énoncé dans la spécification de la langue. Ils peuvent être insérés si le compilateur JIT en a envie, ou pas si ce n'est pas le cas.

Il n'y a pas de mot-clé inline en C #, car c'est une optimisation qui peut généralement être laissée au compilateur, en particulier dans les langages JIT'ed. Le compilateur JIT a accès aux statistiques d'exécution, ce qui lui permet de décider de ce qu'il faut aligner beaucoup plus efficacement que vous ne pouvez le faire en écrivant le code. Une fonction sera inline si le compilateur décide de le faire, et il n'y a rien que vous puissiez faire à ce sujet. :)




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 aboutissent à des actions similaires mais légèrement différentes à effectuer. Considérons par exemple un comparateur de type complexe (non piloté par DB) où l'algorithme de tri trie les éléments en fonction d'un certain nombre de critères différents, comme 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 auxiliaires pour gérer ces actions afin de maintenir la lisibilité et la modularité du code source.

Je sais que ces fonctions auxiliaires devraient être intégrées parce que c'est ainsi que le code serait écrit s'il ne devait jamais être compris par un humain. Je voudrais certainement m'assurer dans ce cas qu'il n'y avait aucune fonction appelant des frais généraux.




Cody a raison, mais je veux donner un exemple de ce qu'est une fonction inline.

Disons que vous avez ce code:

private void OutputItem(string x)
{
    Console.WriteLine(x);

    //maybe encapsulate additional logic to decide 
    // whether to also write the message to Trace or a log file
}

public IList<string> BuildListAndOutput(IEnumerable<string> x)
{  // let's pretend IEnumerable<T>.ToList() doesn't exist for the moment
    IList<string> result = new List<string>();

    foreach(string y in x)
    {
        result.Add(y);
        OutputItem(y);
    }
    return result;
}

L'optimiseur Just-In-Time du compilateur peut 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:

public IList<string> BuildListAndOutput(IEnumerable<string> x)
{
    IList<string> result = new List<string>();

    foreach(string y in x)
    {
        result.Add(y);

        // full OutputItem() implementation is placed here
        Console.WriteLine(y);   
    }

    return result;
}

Dans ce cas, nous dirions que la fonction OutputItem () était en ligne. Notez qu'il peut le faire même si le OutputItem () est appelé depuis d'autres endroits.

Edité pour montrer un scénario plus susceptible d'être en ligne.




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!




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 au moment JIT. Mais je ne sais pas si c'est vraiment faire de telles optimisations.
(Je pense que ça devrait :-))