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

Algorithmes et structures de données Discussion :

Le plus rapide ? if x. if y imbriqués ou if x et y ?


Sujet :

Algorithmes et structures de données

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 29
    Points : 29
    Points
    29
    Par défaut Le plus rapide ? if x. if y imbriqués ou if x et y ?
    Bonjour

    Savez-vous quel est le plus rapide en éxécution ? La différence est-elle significative ou négligeable ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if machin then
      if truc then
         ' traitement
      endif
    endif
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    if (machin and truc) then
      traitement
    endif
    Si la réponse dépend du langage alors j'irai poser cette question sur le forum DOTNET (je bosse en vb.net)


    Merci

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    C'est le genre de question qu'on ne devrait jamais avoir à se poser. Si c'est ce genre d'instruction qui ralentit les perfs de ton appli, c'est que le reste de ton programme doit être écrit en ASM ultra optimisé.

    Je pense que la bonne réponse dans ce cas est la suivante : adopte la syntaxe qui soit la plus claire et la plus explicite pour les gens qui vont lire le code.

    Pour tout de même répondre à ta question, il faudrait regarder le code généré par le compilo mais à mon avis c'est identique dans les deux cas.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 29
    Points : 29
    Points
    29
    Par défaut
    Merci LOULOU

    Ce n'est donc pas là que je pourrai gagner du temps d'éxécution.
    C'était mon avis, mais je préférais avoir une confirmation


    Merci

  4. #4
    Membre régulier
    Inscrit en
    Décembre 2003
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 99
    Points : 82
    Points
    82
    Par défaut
    Bonjour,

    La réponse ne dépend pas du langage, puisqu'au final tout est compilté en Assembleur .

    La deuxieme méthode est plus rapide, car elle necessite qu'un seul saut conditionel ('je' en assembleur).

    La deuxieme méthode est plus lente. Cependant, il est possible que le compilateur optimise ce genre de code et le rende au final aussi rapide .

    Voila ce que le Vb.NET génére comme code machine :

    Méthode 1 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
            If (a) Then
    00000025  test        esi,esi 
    00000027  je          00000030 
                If (b) Then
    00000029  test        ebx,ebx 
    0000002b  je          0000002F 
                    c = False
    0000002d  xor         edi,edi 
                End If
    0000002f  nop              
            End If
    Méthode 2 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
            If (a And b) Then
    00000025  mov         eax,esi 
    00000027  and         eax,ebx 
    00000029  je          0000002D 
                c = False
    0000002b  xor         edi,edi 
            End If
    Je sais qu'on est dans le forum algo et qu'il ne devriait pas avoir de code assembleur, mais il faut le considerer comme une simple illustration à ma réponse

    Citation Envoyé par jennings
    Ce n'est donc pas là que je pourrai gagner du temps d'éxécution
    Ca dépend, si ce code est contenu dans 3 ou 4 boucles imbriqué, ou si il est répeté des milliers de fois, ca peut jouer ...

    Sinon , c'est négligable, d'ailleurs d'un point de vue algo et comprehension, si ton code se résume à ca (pas de else dans la deuxieme condition), il vaut mieux utiliser la deuxieme méthode

    A+
    "Il n'existe que deux choses infinies, l'univers et la bêtise humaine... mais pour l'univers, je n'ai pas de certitude absolue." A. Einstein

  5. #5
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut Re: Le plus rapide ? if x. if y imbriqués ou if x et y ?
    Citation Envoyé par jennings
    Savez-vous quel est le plus rapide en éxécution ? La différence est-elle significative ou négligeable ?
    Ca dépend de beaucoup de choses... En fait, la question que tu te poses pourrait être reformulée ainsi : "Est-il rentable de ne pas faire d'évaluations booléennes complètes ?", et la réponse est en général "Oui".

    Donc, cette forme est en moyenne et en général (j'insiste bien sur ces deux mots !!) plus efficace :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if machin then
      if truc then
         ' traitement
      endif
    endif
    En fait, j'utilise ce genre de choses lorsque je n'ai pas envie (ou que je ne me rappelles plus) l'ordre d'évaluation d'une condition, ou que je veux forcer une évaluation tronquable même dans les langages qui ne le supportent pas.

    Cependant, si tu veux gagner du temps à ce niveau, plusieurs facteurs sont à prendre en compte :
    - Les tests ne doivent pas, si possible, avoir de clauses "else" : ça complexifie l'arrangement manuel des expressions.
    - Il faut connaître la probabilité "être faux" de chaque condition, et tester la plus fréquente en premier.
    - Il faut connaître le temps de calcul, même approximatif, de chaque condition, et tester la plus lente en dernier.
    - Il faut connaître l'interdépendance des conditions entre elles, et bien sûr ne pas tester une dépendance avant son prérequis.
    - Il faut savoir combien de fois est exécuté le test général : si c'est une seule fois dans le programme, laisse le test tranquille. Si c'est 200 fois par milliseconde, ça devient rentable.

    On peut pousser plus avant si tu en as besoin, mais je pense que tu t'es déjà rendu compte que ça demandait des calculs de probas, de vitesse d'exécution et de nombre d'exécutions... Bref, ça ne s'optimise pas "comme ça".
    Pour la même raison, le gain est extrêmement variable... Ca peut être 0.3 ns de gain (ridicule), ou 200 ms (rentable), tout dépend de tes conditions, de leur temps de calcul et de leur probabilité d'être évaluées "fausses".

    Mais surtout, comprends bien que c'est un gain moyen : sur certains tests (les plus nombreux si tu l'as bien fait), ce sera un gain, mais ce sera toujours une perte lorsque toutes les conditions seront vraies !! Tu comprends donc bien l'intérêt des probabilités !

    chicorico Un saut conditionnel non-exécuté ne coûte que très très peu de cycles CPU, car on ne vide pas le pipeline d'exécution. Ton exemple n'est valide que parceque ce sont deux variables, avec un seul test "simple". Essaie avec "a And (Not(b))", ou transforme "b" en appel de fonction et ce sera la première méthode la plus rapide.
    Entre parenthèses, pour l'instruction de saut, on écrit plutôt "jz" (Jump if Zero) plutôt que "je" (Jump if Equal), c'est plus mnémotechnique, même si l'opcode généré est le même.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  6. #6
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Pour completer un peu Mac LAK, il faut que tu sache si ton langage supporte l'évaluation paresseuse.

    En effet, si tu as :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (a and b and c and d and ... and z ) then
     fct
    end if
    dans ce cas, dans un langage qui ne supporte pas l'evaluation paresseuse va effectuer tous les test et même si a est faux alors il va tester les autres même si on sait que celà ne sert à rien, donc dans ce cas, il y a bien gain d temps à imbriquer les if (mais à un temps de codage plus long).

    En revanche, si ton programme effectue l'évaluation paresseuse, il va effectuer le test sur chacune des variables et si l'une d'entre elle est fausse il arrête les tests. Donc en gros (je ne suis pas spécialiste dans les langages), lors de la compilation les structures :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    if (a and b) then
     fct;
    end if;
    doit surement être transformé en

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if (a) then
     if(b) then
      fct
     end if;
    end if;
    Donc en gros dans de tels langages que tu écrives dans un sens ou dans l'autre, il n'y a aucune différence (c'est ce que je pense, il faudrait que quelqu'un confirme).

    Ta réponse dépendra donc à la fois de la probabilités de chacune des variables à être vraie ou fausse (suivant tes tests) mais aussi du langage utilisé.

    PS : si ce genre de tests ne se produisent que très rarement dans ton code : ne te soucis pas de telles questions, réfléchis plus sur les algorithmes utilisés que sur la syntaxe des structures de contrôle utilisées (bien que ce soit interressant)

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 29
    Points : 29
    Points
    29
    Par défaut
    Merci à tous pour vos remarques intéressantes et très circonstanciées.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 34
    Points : 9
    Points
    9
    Par défaut
    Bon, vous allez peut-être trouver ça bête, mais je voulais juste dire que je trouvais ce sujet intéressant à lire.

    Jean.

  9. #9
    Membre éclairé
    Inscrit en
    Juin 2005
    Messages
    644
    Détails du profil
    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2005
    Messages : 644
    Points : 754
    Points
    754
    Par défaut
    en fait si on execute if ( A X B ) X etant un opérateur logique, avec delphi on peut avoir les 2 situations suivantes suvant l'insersion de {$b+} ou {$b-}

    En mode {$B+}, le compilateur génère un code évaluant entièrement les expressions booléennes. Tous les opérandes des expressions booléennes contenant des opérateurs and et or sont alors évalués, même si le résultat de l'expression totale est déjà connu.
    En mode {$B-}, le compilateur génère un code d'évaluation "court-circuit" des expressions booléennes. Cela signifie que l'évaluation s'arrête à partir du moment où le résultat de l'expression devient évident dans l'ordre d'évaluation de gauche à droite.

    en general $b- conduit à une execution + rapide si on met en 1er la booléenne qui a le + de chance de définir de façon univoque le résultat. MAIS, si A et /ou B ne sont pas des booléennes. mais le résultat de fonction retournant une booléenne, on peut court-circuiter l'execution de routines et aller à de sérieux ennuis. D'un autre côté si l'execution de B est assujetti à un retour True de A passer $b- à $b+ conduit à des erreurs.
    ici tout est question d'analyse de la situation en cours.

    on note que $b peut être changé au long du source code suivant les necessites du moment.

  10. #10
    mat.M
    Invité(e)
    Par défaut
    Comme le démontre Chicorico ( qui pourtant se contredit dans ses propos ) la 2ième solution semble + rapide car il n'ya qu'une seule instruction logique ( and )
    Il faut voir qu'un 2ième if peut entrainer un saut en mémoire ce que montre le code ASM de Chicorico
    Et les sauts en mémoires avec je , jg (i386) et compagnie ça peut ralentir les performances

  11. #11
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    En marge des perfs, il est parfois critique de savoir comment est évaluée une expression booléenne. Voici un exemple C/C++:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (ptr && ptr->value==0)
    {
    ...
    }
    De nombreux programmeurs usent et abusent de ce genre d'écriture (dont moi ). En C/C++, l'expression est évaluée de gauche à droite et s'arrête dès que la condition n'est plus vérifiée. Je n'ai pas le souvenir qu'il existe de directives de compil pour changer cela, et heureusement, sans quoi pas mal de code ne serait pas portable.
    Je me souviens de l'époque du TurboPascal, où, en effet une directive permettait de choisir la manière d'évaluer les expressions booléennes.
    Et j'ai enragé le jour où j'ai commencé à faire du vb car là, les expressions sont évaluées en entier

  12. #12
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 119
    Points
    28 119
    Par défaut
    Citation Envoyé par camboui
    En C/C++, l'expression est évaluée de gauche à droite et s'arrête dès que la condition n'est plus vérifiée.
    Cela vient du fait que dans les langages que tu cites, l'exécution est dite "paresseuse". ce n'est pas le cas dans d'autres langages, tout simplement.
    A priori, c'est configurable à la compilation dans pas mal de compilateurs.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  13. #13
    Expert éminent
    Avatar de neguib
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 627
    Détails du profil
    Informations personnelles :
    Âge : 63
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 627
    Points : 7 879
    Points
    7 879
    Par défaut
    jennings comme tu code VB tu peux utiliser l'operateur logique AndAlso
    c'est l'équivalent de If suivi d'un autre If
    Pour le bien de ceux qui vous lisent, ayez à coeur le respect du forum et de ses règles

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. recherche arborescence plus rapide
    Par e-steel dans le forum VB 6 et antérieur
    Réponses: 19
    Dernier message: 30/01/2006, 16h22
  2. Réponses: 16
    Dernier message: 19/05/2005, 16h20
  3. [FB1.5]Quelle est la requete la plus rapide ?
    Par Sitting Bull dans le forum SQL
    Réponses: 4
    Dernier message: 10/12/2004, 13h46
  4. [VB6] timer plus rapide que 1 d'interval
    Par windob dans le forum VB 6 et antérieur
    Réponses: 12
    Dernier message: 24/02/2004, 00h16
  5. Réponses: 8
    Dernier message: 31/10/2003, 16h21

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