60 votes

Comment est la Chaîne dans une instruction switch plus efficace que le correspondant if-else?

La documentation Java dit

Le compilateur Java génère généralement plus efficace de pseudo-code binaire à partir d'instructions de commutation qui utilisent des objets de Chaîne que de enchaînés if-then-else.

Autant que je sache, même Chaîne dans le commutateur utilise .equals() en interne, en tenant compte de la casse. Alors, quelle efficacité signifient-ils dans ce contexte. Une compilation plus rapide? Moins de bytecode ? de meilleures performances?

74voto

Erwin Bolwidt Points 5566

À l'aide d'une instruction switch est plus rapide que equals (mais seulement sensiblement lorsqu'il y a plus que quelques chaînes), car il utilise tout d'abord l' hashCode de la chaîne de l' switch pour déterminer le sous-ensemble de toutes les chaînes qui pourrait éventuellement correspondre. Si plus d'une corde dans le cas des étiquettes a le même hashCode, la JVM va effectuer séquentielle des appels d' equals , et même si il y a une seule chaîne de caractères dans le cas des étiquettes qu'un hashCode, la JVM doit appeler equals pour confirmer que la chaîne dans le cas de l'étiquette est vraiment égal à celui de l'interrupteur d'expression.

Les performances d'exécution d'un interrupteur sur des objets de Chaîne est comparable à une recherche dans une HashMap.

Ce morceau de code:

public static void main(String[] args) {
    String s = "Bar";
    switch (s) {
    case "Foo":
        System.out.println("Foo match");
        break;
    case "Bar":
        System.out.println("Bar match");
        break;
    }
}

Est à l'intérieur compilé et exécuté comme ce morceau de code:

(pas littéralement, mais si vous décompiler les deux morceaux de code que vous voyez que exactement la même séquence d'actions)

final static int FOO_HASHCODE = 70822; // "Foo".hashCode();
final static int BAR_HASHCODE = 66547; // "Bar".hashCode();

public static void main(String[] args) {
    String s = "Bar";
    switch (s.hashCode()) {
    case FOO_HASHCODE:
        if (s.equals("Foo"))
            System.out.println("Foo match");
        break;
    case BAR_HASHCODE:
        if (s.equals("Bar"))
            System.out.println("Bar match");
        break;
    }
}

20voto

Tyler Points 1726

En général, les instructions switch sont mieux parce qu'ils sont (grosso modo) O(1), tandis qu'une chaîne de if-else est O(n)

Ayant n conditions pourrait entraîner n des comparaisons à l'aide d'un enchaînés if-else des déclarations.

Une instruction switch peut "sauter" directement à la condition, si elle existe (comme une carte), ou au cas par défaut si elle existe, rendant O(1).

7voto

Evgeniy Dorofeev Points 52031

C'est un bytecode fragment généré à partir de l'exemple de la doc:

 INVOKEVIRTUAL java/lang/String.hashCode ()I
    LOOKUPSWITCH
      -2049557543: L2
      -1984635600: L3
      -1807319568: L4

à l'aide de LOOKUPSWITCH a une meilleure performance par rapport à si-sinon la logique

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