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

 C Discussion :

rapidité du switch vs if/else


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    autre
    Inscrit en
    Octobre 2018
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Octobre 2018
    Messages : 30
    Points : 21
    Points
    21
    Par défaut rapidité du switch vs if/else
    Bonjour,

    de la discussion suivante

    Pourquoi fact_res_1 est-elle plus rapide que fact_res_2 ?

    j'ai appris que
    Le switch étant [légèrement] + efficace parce qu'il utilise 1 table de sauts
    Après une légère recherche, une table de saut (ou table de correspondance/Lookup table) est une liste d'associations de valeurs.

    Comment dans le cas d'un test tel que, if (n == 1) ou if (n != 1) une telle table peut-elle être construit ?

    ça ne va quand même pas faire un tableau de n cases avec faux à toutes les cases sauf la première pour if (n == 1) et un tableau de n cases avec vrai à toutes les cases sauf la première pour if (n != 1).

    Car dans ce cas:

    ce mécanisme ne pouvant s'appliquer qu'à l’exécution (la valeur de n étant inconnu à la compilation).
    le travail à effectuer, n comparaisons, pour créer la table n'est-il pas équivalent aux n tests ( (n == 1) / (n !*= 1) ) ? donc implique un coût identique.

    la seule manière de "rentabilise" la création de cette table serait un accès fréquent à la fonction contenant le test (double récurrence ou autres).
    À cela il faudrait ajouter le coût de la place en mémoire ainsi que son accès (tests if-else dans les registre du CPU Vs accès en RAM voir mémoire virtuelle).

    Seul si le calcul, dans la comparaison, est une formule compliquer voir un appel de fonction, il semble y avoir un bénéfice.

    A cela on peut ajouter le cas suivant:
    version if-else
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    	if(A) {
    		do 1;
    	} 
    	then if (B) {
    		do 2;
    	} 
    	then if (C) {
    		do 3;
    	}
    	else {
    		do 4;
    	}
    version switch
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    switch(c) {
     
    		case(A):
    			do 1;
    		case(B):
    			do 2;
    		case(C):
    			do 3;
    		default:
    			do 4;
    	}
    si le cas (A) est à 98% celui qui est rencontré
    dans le cas du if, (B) et (C) ne seront quasiment jamais calculés et le switch s’embarrasse d'une table ne lui servant à presque rien.

    Tout ceci n’étant que supposition il en demeure une autre: si le swith et plus optimal que if-else le compilateur n'aurait-il pas intérêt à transformer les if-else en switch.

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par primusG Voir le message
    si le swith et plus optimal que if-else le compilateur n'aurait-il pas intérêt à transformer les if-else en switch.
    Pas possible. Tu n'as probablement pas compris ce qu'est une table de saut: c'est un goto.
    Le switch c'est juste une collection d'étiquettes (tu remarqueras le double-point terminant les valeurs dans les "case" exactement comme un double-point termine un label permettant ensuite un goto label). Et donc quand la valeur "switchée" est calculée, si elle vaut "caseX" il est alors exécuté un goto caseX.
    Il en résulte que les valeurs des case ne peuvent être que des constantes. Tandis qu'un if peut, lui, évaluer des variables et/ou des expressions.
    Pour résumer, tu peux écrire if (fctA() == fctB()) { xxx } else { yyy }, les fonctions seront appelées lors de l'évaluation. Mais tu ne peux pas convertir cette expression en un truc qui, d'après ce que tu décris, devrait ressembler à
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    switch (fctA()) {
    	case fctB(): xxx; break;
    	default: yyy;
    }
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Dans ton sujet, avec la bonne optimisation, que soit le if ou le switch, c'est le même résultat.
    En regardant sur Internet très vite fait gcc semble grandement ne pas utiliser les tables de correspondance (LUT)

    À partir d'ici tout est hyper théorique

    Ce que tu sembles ne pas avoir compris, dans 1 LUT tu dois mettre 1 pointeur de fonction (ou directement le code en mode "inline" (ne me demande pas le comment )).
    Pour 1 switch :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        switch(c) {
        case(1):
            do 1;
        case(2):
            do 2;
        default:
            do 3;
        }
    Devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    | case 0: pointeur vers do1 | case 1: pointeur vers do2 | case 2: pointeur vers do3 |
    Tu vois que tu transformes 1 [série de] test (c == 1, c == 2, ...) en index LUT[(c - 1)] ((c - 1) doit être clampé sur l'intervalle 0 <-> 2, donc effectivement 1 test si l'index est non signé)

    Oui c'est très théorique parce qu'il faut prendre en compte l'espace entre les valeurs, le nombres de cas (tu l'as évoqué), ...
    J'ai vu que sur ARM, tu avais 1 LUT prévu avec 16 indexes.

    Regarde mon message : if (n != 1), tu ne peux pas le transformer en switch parce que tu as 1 infinité de possibilité (c'était mon point)
    Mais if (n == 1), tu peux le convertir en switch d'1 seul cas et 1 défaut : donc 1 LUT de 2 cases
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    | case 0: pointeur vers le code (n==1) | case 1: pointeur vers le défaut |

    Édit : le vrai terme c'est jump table/ branch table. branch table, lien wikipedia en anglais
    le lien reprend les 2 méthodes : celle de @Sve@r (avec les goto) et la mienne (avec les pointeurs)

Discussions similaires

  1. Fonction avec 3 switch ou if else selon le navigateur employé
    Par patricktoulon dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 13/02/2018, 23h44
  2. Passage de structure else if à switch case
    Par stefsas dans le forum C#
    Réponses: 1
    Dernier message: 13/07/2010, 10h47
  3. If /Else & Switch case avec plusieurs paramètres
    Par ralek dans le forum Débuter avec Java
    Réponses: 6
    Dernier message: 07/07/2010, 19h28
  4. switch ou else if
    Par raph707 dans le forum Langage
    Réponses: 14
    Dernier message: 26/05/2007, 21h22
  5. [Système] switch ou if-then-else
    Par boniface dans le forum Langage
    Réponses: 5
    Dernier message: 13/07/2006, 21h42

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