IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

[Système] rapidité d'exécution if <> switch


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé Avatar de lalouve
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2004
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2004
    Messages : 128
    Par défaut [Système] rapidité d'exécution if <> switch
    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!

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    774
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2005
    Messages : 774
    Par défaut
    si c'est une seule alternative c'est pas la peine d'utiliser un switch

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    150
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 150
    Par défaut
    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 ^^

  4. #4
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Par défaut
    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.

  5. #5
    Membre émérite Avatar de trattos
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    1 000
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 000
    Par défaut
    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.

  6. #6
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Par défaut
    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
    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;
     
    	}
    }
     
    ?>
    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
    <?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;
    	}
    }
     
    ?>
    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
    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.

    La seule configuration éventuellement nécessaire est la variable $iterations située à la ligne 16 de index.php.

  7. #7
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Par défaut
    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 ?

  8. #8
    Membre chevronné Avatar de XtofRoland
    Profil pro
    Inscrit en
    Août 2005
    Messages
    357
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2005
    Messages : 357
    Par défaut
    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; 
       } 
    } 
     
    ?>
    je pense que ce elseif n'est pas comparable au switch car dans ton switch tu as mis des break...
    donc si le cas 1 arive plus souvent tu evite les tests suivants.
    alors que tu te les tapes tous dans le elseif.

  9. #9
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Par défaut
    alors que tu te les tapes tous dans le elseif.
    Non, un if elseif tout comme un switch, ne traitera pas les autres tests
    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";		
    	}

  10. #10
    Membre chevronné Avatar de XtofRoland
    Profil pro
    Inscrit en
    Août 2005
    Messages
    357
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2005
    Messages : 357
    Par défaut
    je viend de tester :
    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";       
       }
    ca n'imprime que le A, bien vu
    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.

  11. #11
    Membre émérite
    Avatar de Kioob
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    550
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2004
    Messages : 550
    Par défaut
    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.

  12. #12
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Par défaut
    @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.

  13. #13
    Membre Expert
    Inscrit en
    Juillet 2004
    Messages
    1 027
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 027
    Par défaut
    Pour en revenir à la question de départ

    dans le cas d'une seule alternative un switch est-il plus rapide qu'un if?
    La différence est tellement insignifiante que sa mesure à la vitesse de frappe sur le clavier

Discussions similaires

  1. [Système] Erreur d'exécution d'un petit script
    Par couscoussier dans le forum Langage
    Réponses: 3
    Dernier message: 04/04/2006, 10h04
  2. [Système] problème d'exécution d'une boucle
    Par WalidNat dans le forum Langage
    Réponses: 6
    Dernier message: 02/04/2006, 00h55
  3. [Système] Problème d'exécution .sh
    Par sebeni dans le forum Langage
    Réponses: 9
    Dernier message: 24/01/2006, 14h17
  4. [Système] Forcer l'exécution d'un code php
    Par florent dans le forum Langage
    Réponses: 4
    Dernier message: 02/12/2005, 13h13
  5. Réponses: 5
    Dernier message: 19/04/2005, 08h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo