Dans un commutateur vs dictionnaire pour une valeur de Func, qui est plus rapide et pourquoi?

Suppose qu'il y a le code suivant:

private static int DoSwitch(string arg)
{
    switch (arg)
    {
        case "a": return 0;
        case "b": return 1;
        case "c": return 2;
        case "d": return 3;
    }
    return -1;
}

private static Dictionary<string, Func<int>> dict = new Dictionary<string, Func<int>>
    {
        {"a", () => 0 },
        {"b", () => 1 },
        {"c", () => 2 },
        {"d", () => 3 },
    };

private static int DoDictionary(string arg)
{
    return dict[arg]();
}

Par itération sur les deux méthodes et en les comparant, je suis arriver que le dictionnaire est un peu plus rapide, même lorsque "a", "b", "c", "d" est élargi pour inclure plus de touches. Pourquoi est-ce donc?

Est ce que cela a à voir avec la complexité cyclomatique? Est est parce que la gigue compile le retour des déclarations dans le dictionnaire en code natif qu'une seule fois? Est-ce parce que la recherche du dictionnaire est O(1), qui peut être pas le cas pour une instruction switch? (Ce ne sont que des suppositions)

  • Le compilateur peut réellement transformer votre switch dans un dictionnaire à un certain point, alors assurez-vous de tester avec le réel de l'entrée.
  • Lors de l'examen du code de langage, il semble que la seule mise en cache anonyme délégués sont pour le dictionnaire, pas pour les instructions de commutation.
  • Je me demandais, pourquoi votre dictionnaire <string, Func<int>> au lieu de simplement <string, int>?
  • Je veux le rendre plus général, depuis le Funcs va changer, mais je voulais voir un dictionnaire de la valeur de Func dans la base de cas.
  • Le compilateur génère du code différemment sur la base de l'interrupteur/cas.
  • Rasmussen: voulez-vous dire que le compilateur ou l'interpréteur? De ce que je vois, le code généré IL est pour l'instruction switch. Cependant, je ne sais pas ce que le CLR convertit au moment de l'exécution.
  • Le compilateur C# génère différents IL code en fonction de la taille de la switch/case code est.
  • Comme le nombre de cas dans l'instruction switch grandit, le code généré par le compilateur peut changer à mesure que le compilateur commutateurs de tactiques et de tirer parti des tendances observées dans le code source. Je ne sais pas si désinvolte C# ou compilateurs JIT effectuer cette optimisation, mais d'un commun compilateur truc pour les instructions de commutation lorsque le cas des sélecteurs sont pour la plupart séquentielle consiste à calculer un saut de vecteur. Cela exécute en temps constant. Soustraire arg - "un", utiliser le résultat comme index dans la table de saut pour sauter, le cas échéant, bloquer.

InformationsquelleAutor cubetwo1729 | 2012-07-23