Salut,
pitite question de rapidité d'exécution :
dans le cas d'une seule alternative un switch est-il plus rapide qu'un if?
A ceux qui savent et qui répondent, merci!
Salut,
pitite question de rapidité d'exécution :
dans le cas d'une seule alternative un switch est-il plus rapide qu'un if?
A ceux qui savent et qui répondent, merci!
si c'est une seule alternative c'est pas la peine d'utiliser un switch
Qu'on me reprenne si je me trompe, mais un switch ne sera jamais plus rapide à l'exécution qu'une série de if.
Peut-être que mes souvenirs sur certains benchmarks me reviennent un peu corrompus ^^
Salut
Perso, je ne vois pas l'utilité d'un switch s'il n'y a qu'une alternative et aucun moyen que le code évolue... Il est principalement utile pour des questions de lisibilité, or cet argument n'est pas valable dans le cas d'une simple alternative.
Je sens que je vais faire un bench maison pour comparer ces deux structures.
Mes articles - Zend Certified Engineer (PHP + Zend Framework)
Ressources PHP - Ressources Zend Framework - Cours et tutoriels pour apprendre PHP - Forum PHP
Rappel:
Le switch est une sélection effectué sur une variable pour plusieurs valeurs.
Le if est une condition applicable dans n'importe quel cas.
J'ai fait un petit benchmark, je ne sais pas si c'est très précis mais voilà, dans la situation testée par mes soins, le switch semble avoir besoin de 93-95% du temps d'un if/else.
Un bémol cependant : les résultats sont différents si j'utilise une boucle while au lieu d'une boucle for... Les temps moyens se rapprochent beaucoup.
Si quelqu'un peu m'expliquer cela, je lui en serais reconnaissant. Merci.
Eh bien j'ai l'impression que ce que je pensais est confirmé : la structure switch semble légèrement plus rapide qu'une série de if/else, si toutefois on prend des conditions identiques. En fait, ça me paraît logique puisque c'est toujours la même variable, donc PHP s'en souvient d'un case à l'autre ; pour if/else, PHP est obligé d'aller chercher la valeur de la variable à chaque nouveau test, ce qui lui fait perdre un pouillème de seconde de plus.
Je vous donne le code :
index.php
ifelse.php
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 <?php function microtime_float() { list($usec, $sec) = explode(' ', microtime()); return ((float)$usec + (float)$sec); } session_start(); if(!empty($_GET['start_over'])){ $_SESSION['switch'] = array(); $_SESSION['ifelse'] = array(); } $var = 'bouh'; $iterations = 5000000; $start_time = microtime_float(); ?> <a href="index.php?what=switch">switch</a> - <a href="index.php?what=ifelse">if/else</a> - <a href="index.php?start_over=true">START OVER</a><br /><br /> <?php if(!empty($_GET['what'])){ include($_GET['what'].'.php'); $_SESSION[$_GET['what']][] = microtime_float() - $start_time; } foreach(array('switch', 'ifelse') as $what){ $array_count = count($_SESSION[$what]); if($array_count > 0){ $moyenne[$what] = bcdiv(array_sum($_SESSION[$what]), $array_count, 5); echo 'Moyenne de '.$what.' : '.$moyenne[$what].' s ('.$array_count.' tests)<br />'; } } if(!empty($moyenne)){ $message = 'Le gagnant est le <b>%s</b> avec un temps d\'exécution égal à <b>%s</b> du %s<br />'; if($moyenne['switch'] < $moyenne['ifelse']){ echo sprintf($message, 'switch', bcdiv($moyenne['switch'] * 100, $moyenne['ifelse'], 3).'%', 'if/else'); } else{ echo sprintf($message, 'ifelse', bcdiv($moyenne['ifelse'] * 100, $moyenne['switch'], 3).'%', 'switch'); } } if(empty($_GET['stop']) and !empty($_GET['what'])){ switch($_GET['what']){ case 'ifelse': ?><script language="javascript">location.replace('index.php?what=switch');</script><?php break; case 'switch': ?><script language="javascript">location.replace('index.php?what=ifelse');</script><?php break; } } ?>
switch.php
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 <?php $cpt = 0; //for($i=0; $i<$iterations; ++$i){ while($cpt<$iterations){ if($var == 'bleh0'){ } else if($var == 'bleh1'){ } else if($var == 'bleh2'){ } else if($var == 'bleh3'){ } else if($var == 'bleh4'){ } else{ ++$cpt; } } ?>
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 <?php $cpt = 0; //for($i=0; $i<$iterations; ++$i){ while($cpt<$iterations){ switch($var){ case 'bleh0': break; case 'bleh1': break; case 'bleh2': break; case 'bleh3': break; case 'bleh4': break; default: ++$cpt; } } ?>
Surtout, ne prenez pas les résultats de ce code à la lettre tant que d'autres ne l'auront pas testé et validé... Merci.
Utilisation : lancez l'index et cliquez sur l'un des deux premiers liens. Pour arrêter les tests (ça se relance tout seul...), il faut stopper le script et le rappeler avec une valeur dans le paramètre "stop" de l'URL.
Laissez-le tourner un moment tout seul, il va tester switch et if/else par alternance.
Code : Sélectionner tout - Visualiser dans une fenêtre à part index.php?stop=true
La seule configuration éventuellement nécessaire est la variable $iterations située à la ligne 16 de index.php.
Mes articles - Zend Certified Engineer (PHP + Zend Framework)
Ressources PHP - Ressources Zend Framework - Cours et tutoriels pour apprendre PHP - Forum PHP
Je pense que tu gagne en performance dans les deux cas si tu place le cas le plus fréquent en premier.
Maintenant, il serait intéressant d'avoir un cas concret pour faire des optimisations, si tu as un bout de code ?
je pense que ce elseif n'est pas comparable au switch car dans ton switch tu as mis des break...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 <?php $cpt = 0; //for($i=0; $i<$iterations; ++$i){ while($cpt<$iterations){ if($var == 'bleh0'){ } else if($var == 'bleh1'){ } else if($var == 'bleh2'){ } else if($var == 'bleh3'){ } else if($var == 'bleh4'){ } else{ ++$cpt; } } ?>
donc si le cas 1 arive plus souvent tu evite les tests suivants.
alors que tu te les tapes tous dans le elseif.
Non, un if elseif tout comme un switch, ne traitera pas les autres testsalors que tu te les tapes tous dans le elseif.
sitot qu'il a trouvé une entrée.
Essaie ce code:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 function toto($msg) { echo $msg; return 1; } if(1==toto('a')) { echo "A"; } elseif(2==toto('b')) { echo "B"; } else { echo "C"; }
je viend de tester :
ca n'imprime que le A, bien vu
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 $a = 'a'; $b = 'b'; if($a == 'a') { echo "A"; } elseif($b =='b') { echo "B"; } else { echo "C"; }
et le for il recalcule la valeur du i (en supposant que c'est $i ;-))
est ce lié a la version de php ou est ce définit par le langage?
en delphi par exemple selon le compilateur le i avait des valeur différente a la sortie de la boucle...
si tu as un lien vers ce genre d'articles ;-) je suis preneur.
euh.... ton benchmark.... mffff.... tu mélanges tellement de trucs que du coup je ne sais meme pas ce qui est compté mais certainement pas les perfs du "if " ou du "switch"Là tu as les sessions, le javascript, le navigateur, Apache, le cache d'opcode, la connexion, les ressources du serveur, etc etc qui entrent en jeu... à tel point que le peu de différence qu'il y aura entre les deux structures PHP n'influera pas du tout sur les résultats.
Pour faire un bon benchmark d'après moi il faut limiter au maximum les facteurs externes, ou bien utiliser des conditions réelles. Ce qui n'est pas du tout le cas ici.
@Kioob : je ne demande pas mieux que d'apprendre à faire des benchs (notamment). J'ai d'ailleurs prévenu à l'avance et aussi après-coup que ce n'est sûrement pas le meilleur bench que l'on puisse faire.
Cela dit, J'ai effectivement commencé par limiter les facteurs externes puis j'ai ajouté les sessions, le JS et les stats au fur et à mesure. Pas de différence notable.
Développez.com est un forum d'entraide, j'y suis allé de la solution que je pensais correspondre et je l'ai fait sans prétention, avec mise en garde même. Je ne demande pas mieux que de rectifier le tir s'il y a besoin de le faire : merci de me le faire savoir avec arguments/explications à l'appui tant que possible.
Mes articles - Zend Certified Engineer (PHP + Zend Framework)
Ressources PHP - Ressources Zend Framework - Cours et tutoriels pour apprendre PHP - Forum PHP
Pour en revenir à la question de départ
La différence est tellement insignifiante que sa mesure à la vitesse de frappe sur le clavierdans le cas d'une seule alternative un switch est-il plus rapide qu'un if?![]()
Partager