web-dev-qa-db-fra.com

L'opérateur ternaire est-il plus rapide qu'une condition "si" en Java?

Je suis enclin à " si-conditionnel syndrome ", ce qui signifie que j'ai tendance à utiliser si des conditions tout le temps. J'utilise rarement l'opérateur ternaire. Par exemple:

//I like to do this:
int a;
if (i == 0)
{
    a = 10;
}
else
{
    a = 5;
}

//When I could do this:
int a = (i == 0) ? 10:5;

Est-ce important que j'utilise? Lequel est plus vite? Existe-t-il des différences de performances notables? Est-il préférable d’utiliser le code le plus court chaque fois que possible?

106
JRunner

Est-ce important que j'utilise?

Oui! La seconde est beaucoup plus lisible. Vous négociez une ligne qui exprime de manière concise ce que vous voulez contre neuf lignes d'encombrement efficace.

Lequel est plus vite?

Ni.

Est-il préférable d’utiliser le code le plus court chaque fois que possible?

Pas «autant que possible» mais certainement chaque fois que cela est possible sans effets néfastes. Un code plus court est au moins potentiellement plus lisible puisqu'il se concentre sur la partie pertinente plutôt que sur les effets fortuits («code standard»).

96
Konrad Rudolph

S'il y a des différences de performances (ce dont je doute), elles seront négligeables. Concentrez-vous sur l'écriture du code le plus simple et le plus lisible possible.

Ceci dit, essayez de surmonter votre aversion pour l’opérateur conditionnel - bien qu’il soit certainement possible de le surexploiter, il peut être réellement utile dans certains cas. Dans l'exemple spécifique que vous avez donné, j'utiliserais certainement l'opérateur conditionnel.

31
Jon Skeet

Exemple d'opérateur ternaire:

int a = (i == 0) ? 10 : 5;

Vous ne pouvez pas faire d'affectation avec if/else comme ceci: 

// invalid:
int a = if (i == 0) 10; else 5;

C'est une bonne raison d'utiliser l'opérateur ternaire. Si vous n'avez pas de mission:

(i == 0) ? foo () : bar ();

un if/else n'est pas beaucoup plus de code: 

if (i == 0) foo (); else bar ();

Dans les cas critiques de performance: mesurez-le. Mesurez-le avec la machine cible, la JVM cible, avec des données typiques, s'il existe un goulot d'étranglement. Sinon aller pour la lisibilité.

Intégré au contexte, la forme abrégée est parfois très pratique:

System.out.println ("Good morning " + (p.female ? "Miss " : "Mister ") + p.getName ()); 
26
user unknown

Oui, c'est important, mais pas à cause des performances d'exécution du code.

Un codage plus rapide (performant) est plus pertinent pour la création de boucles et l'instanciation d'objet que les constructions de syntaxe simple. Le compilateur doit gérer l'optimisation (le binaire sera à peu près le même!). Votre objectif doit donc être l'efficacité pour You-From-The-Future (les humains sont toujours le goulot d'étranglement du logiciel).

Conférence "Performance Anxiety" de Josh Bloch sur Parleys.com

La réponse citant 9 lignes par rapport à une peut être trompeuse: moins de lignes de code n'est pas toujours synonyme de mieux .. Les opérateurs ternaires peuvent être plus concis dans des situations limitées (votre exemple est bon).

MAIS on peut souvent en abuser pour rendre le code illisible (ce qui est un péché capital) = ne pas imbriquer les opérateurs ternaires!

Pensez également à la facilité de maintenance future, s'il est beaucoup plus facile d'étendre ou de modifier:

int a;
if ( i != 0 && k == 7 ){
    a = 10;
    logger.debug( "debug message here" );
}else
    a = 3;
    logger.debug( "other debug message here" );
}


int a = (i != 0 && k== 7 ) ? 10 : 3;  // density without logging nor ability to use breakpoints

p.s. réponse de stackoverflow très complète à ternaire ou non ternaire?

15
foupfeiffer

Les opérateurs ternaires ne sont que des raccourcis. Ils compilent dans l'instruction if-else équivalente, ce qui signifie qu'ils seront exactement identiques.

8
Jon Egeland

De plus, l'opérateur ternaire active une forme de paramètre "facultatif". Java n'autorise pas les paramètres facultatifs dans les signatures de méthode, mais l'opérateur ternaire vous permet d'insérer facilement un choix par défaut lorsque null est fourni pour une valeur de paramètre.

Par exemple:

public void myMethod(int par1, String optionalPar2) {

    String par2 = ((optionalPar2 == null) ? getDefaultString() : optionalPar2)
            .trim()
            .toUpperCase(getDefaultLocale());
}

Dans l'exemple ci-dessus, passer null en tant que valeur du paramètre String vous permet d'obtenir une valeur de chaîne par défaut au lieu d'une NullPointerException. C'est court et doux et, je dirais, très lisible. De plus, comme cela a été souligné, au niveau du code d'octet, il n'y a vraiment pas de différence entre l'opérateur ternaire et le comportement if-then-else. Comme dans l'exemple ci-dessus, la décision à choisir repose entièrement sur la lisibilité.

De plus, ce modèle vous permet de rendre le paramètre String réellement facultatif (si cela est jugé utile) en surchargeant la méthode comme suit:

public void myMethod(int par1) {
    return myMethod(par1, null);
}
4
scottb

Pour l'exemple donné, je préfère l'opérateur ternaire ou l'opérateur de condition (?) pour une raison spécifique: je peux clairement voir que l'attribution de a n'est pas facultative. Avec un exemple simple, il n'est pas trop difficile d'analyser le bloc if-else pour voir que a est affecté à chaque clause, mais imaginez plusieurs affectations dans chaque clause:

if (i == 0)
{
    a = 10;
    b = 6;
    c = 3;
}
else
{
    a = 5;
    b = 4;
    d = 1;
}

a = (i == 0) ? 10 : 5;
b = (i == 0) ? 6  : 4;
c = (i == 0) ? 3  : 9;
d = (i == 0) ? 12 : 1;

Je préfère ce dernier pour que vous sachiez que vous n'avez pas manqué une mission.

1
Matthew Carlson

Il est préférable d’utiliser ce que l’on lit le mieux - il y a dans tous les effets pratiques 0 différence entre les performances.

Dans ce cas, je pense que la dernière déclaration se lit mieux que la première si, mais en prenant soin de ne pas abuser de l'opérateur ternaire - cela peut parfois rendre les choses beaucoup moins claires.

0
Michael Berry

Essayez d'utiliser l'instruction switch case, mais normalement, ce n'est pas le goulot d'étranglement des performances.

0
Zava