80 votes

Qu'est-ce qui est plus rapide, allumer chaîne ou elseif sur type?

Disons que j'ai l'option de l'identification d'un code de la route à prendre, sur la base d'une comparaison de chaînes ou d'autre iffing du type:

Ce qui est plus rapide et pourquoi?

switch(childNode.Name)
{
    case "Bob":
      break;
    case "Jill":
      break;
    case "Marko":
      break;
}

if(childNode is Bob)
{
}
elseif(childNode is Jill)
{
}
else if(childNode is Marko)
{
}

Mise à jour: La principale raison pour laquelle je demande c'est parce que l'instruction switch est perculiar à propos de ce qui compte comme un cas. Par exemple il l'habitude de vous permettre d'utiliser des variables, seules les constantes qui sont déplacés à l'assemblage principal. Je suppose qu'il avait cette restriction en raison de certaines de funk il était en train de faire. Si c'est seulement la traduction de elseifs (comme un poster de commentaire), alors pourquoi ne sommes-nous pas autorisés variables dans le cas des états?

Mise en garde: je suis post-optimisation. Cette méthode est appelée plusieurs fois dans une partie lente de l'application.

19voto

ilitirit Points 4636

Tout d'abord, vous êtes à comparer des pommes et des oranges. Vous auriez besoin d'abord de comparer commutateur de type vs basculer sur la chaîne, et puis si le type vs si sur la chaîne, puis de comparer les gagnants.

Deuxièmement, c'est le genre de chose OO a été conçu pour. Dans les langues qui prennent en charge OO, la commutation sur le type (de toute nature) est une odeur de code qui pointe à une mauvaise conception. La solution est de calculer à partir d'une base commune avec d'un résumé ou de méthode virtuelle (ou similaire à construire, en fonction de votre langue)

par exemple.

class Node
{
    public virtual void Action()
    {
        // Perform default action
    }
}

class Bob : Node
{
    public override void Action()
    {
        // Perform action for Bill
    }
}

class Jill : Node
{
    public override void Action()
    {
        // Perform action for Jill
    }
}

Alors, au lieu de faire de l'instruction switch, il vous suffit d'appeler childNode.Action()

18voto

Greg Points 11257

J'ai juste mis en place un test rapide de l'application et profilé, avec les FOURMIS 4.
Spec: .Net 3.5 sp1 32 bits de Windows XP, code intégré en mode release.

3 millions de tests:

  • Commutateur: 1.842 secondes
  • Si: 0.344 secondes.

En outre, l'instruction switch résultats révèlent (sans surprise) que plus les noms de prendre plus de temps.

1 million de tests

  • Bob: 0.612 secondes.
  • Jill: 0.835 secondes.
  • Marko: 1.093 secondes.

Je dirait que le "if Else" est plus rapide, au moins le scénario que j'ai créé.

class Program
{
	static void Main( string[] args )
	{
		Bob bob = new Bob();
		Jill jill = new Jill();
		Marko marko = new Marko();

		for( int i = 0; i < 1000000; i++ )
		{
			Test( bob );
			Test( jill );
			Test( marko );
		}
	}

	public static void Test( ChildNode childNode )
	{	
		TestSwitch( childNode );
		TestIfElse( childNode );
	}

	private static void TestIfElse( ChildNode childNode )
	{
		if( childNode is Bob ){}
		else if( childNode is Jill ){}
		else if( childNode is Marko ){}
	}

	private static void TestSwitch( ChildNode childNode )
	{
		switch( childNode.Name )
		{
			case "Bob":
				break;
			case "Jill":
				break;
			case "Marko":
				break;
		}
	}
}

class ChildNode	{ public string Name { get; set; } }

class Bob : ChildNode {	public Bob(){ this.Name = "Bob"; }}

class Jill : ChildNode{public Jill(){this.Name = "Jill";}}

class Marko : ChildNode{public Marko(){this.Name = "Marko";}}

12voto

Nescio Points 12613

L'instruction Switch est plus rapide à exécuter que l'échelle if-else-if. Cela est dû à la capacité du compilateur à optimiser l'instruction switch. Dans le cas de l'échelle if-else-if, le code doit traiter chaque instruction if dans l'ordre déterminé par le programmeur. Cependant, comme chaque cas dans une instruction switch ne s'appuie pas sur des cas antérieurs, le compilateur est en mesure de réorganiser les tests de manière à fournir l'exécution la plus rapide.

6voto

Gary Kephart Points 2056

Si les cours sont faits, je suggérerais d'utiliser un modèle de conception Stratégie au lieu de switch ou elseif.

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