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 :

Optimisation de code


Sujet :

C

  1. #21
    Membre éclairé
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Par défaut
    Oui en effet je pensais pas que faire:
    ind3 = t_part[i]->nvar_mone ;

    ca prendrais moins de temps que de mettre directement t_part[i]->nvar_mone .

    Pour memmove, je suppose qu'on gagne du temps ...

    En tout cas merci pr tous ces conseils

  2. #22
    Membre éclairé
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Par défaut
    Pour tes deux derniers exemples, on gagnerai vraiment?
    Parce que finalement si non prends ton premer exemple, on boucle toujours sur k, et on doit en plus incrémenter x0 , donc on ajoute quelques opérations non?

  3. #23
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par vinzzzz
    Oui en effet je pensais pas que faire:
    ind3 = t_part[i]->nvar_mone ;

    ca prendrais moins de temps que de mettre directement t_part[i]->nvar_mone .

    Pour memmove, je suppose qu'on gagne du temps ...

    En tout cas merci pr tous ces conseils
    pour memmove tu gagnes énormément

    Et pour le reste, tu gagnes peu, mais sur beaucoup tu gagnes beaucoup : à chaque fois, tu fais une somme (pour calculer l'adresse) au lieu d'avoir le chiffre déjà prêt...

    Et c'est vrai pour chaque indice. Et pour l'élément du tableau :

    Vaux mieux mettre :

    tab[i] que tab[fonction(i)]
    valtab que tab[i]

    donc si tu fais référence à plusieurs fois le même élément tu le mets dans une variable, si tu fais référence à plusieurs fois le même indice tu le mets dans une variable intermédiaire..

  4. #24
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par vinzzzz
    Pour tes deux derniers exemples, on gagnerai vraiment?
    Parce que finalement si non prends ton premer exemple, on boucle toujours sur k, et on doit en plus incrémenter x0 , donc on ajoute quelques opérations non?
    non

    Quand tu fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
            for(k = t_part[i]->delay_pone ; k > 0  ; k--) {
    	t_part[i]->x[j][k] = t_part[i]->x[j][k-1] ;
    il faut calculer :

    l'adresse t->part[i] : 1 somme (éventuellement *2 si pas flag optimisé)
    l'adresse t->part[i]->x : 1 somme ( kif kif)
    l'adresse t->part[i]->x[j] : 1 somme (kif kif)
    l'adresse t->part[i]->x[j][k] : 1 somme
    l'adresse t->part[i]->x[j][k-1] : 1 somme

    donc entre 5 et 8 sommes


    Alors que dans :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
         for(k = t_part[i]->delay_pone ; k > 0  ; k--) {
                  *x0 = *(x0-1) ;
                    x0= x0 - 1 ;
    calculer x0 -1 : une somme
    l'affecter : une copie ou une somme (dépendant de comment c'est optimisé)

    Donc en net 2 sommes max.


    Il n'y a que là ou je ne suis pas sûr si on gagnerais en faisant :

    p = x0 -1
    *x0 = *p
    x0 = p ;

    mais sans doute (la copie doit prendre moins de temps que la somme)
    et dans ce cas on aurait (une somme + 2 copies)

  5. #25
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par lun4t1k
    Pour en revenir a la complexité, il me semble tout de même que le calcul de la complexité d'un while peut s'avérer plus difficile à calculer lors d'utilisations particulières dans des algos particuliers!

    il existe un algo qui contient un while dont la complexité n'a pu etre déterminée, et je n'en connais pas avec un for! (je n'ai plus l'algo ne demandez pas! )
    Tu as des exemples concrets... (parce que je vois pas à quel niveau il pourrait y avoir une quelconque différence)

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  6. #26
    Membre éclairé
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Par défaut
    Si j'ai bien compris, quand je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    for(j = 0 ; j < t_part[i]->nvar ; j++) {
    	for(k = t_part[i]->delay_pone ; k > 0  ; k--) {
    		t_part[i]->x[j][k] = t_part[i]->x[j][k-1] ;
    	}
    }
    Cette instruction:
    t_part[i]->x[j][k]
    va demander en fait a chaque fois un calcul pour obtenir t_part[i]->x[j], alors que j'aurais pu l'obtenir en une fois juste avant de rentrer dans la deuxième boucle?
    Et de la même manière, puisque j'utilise beaucoup le pointeur qui se trouve a t_part[i], si je stocke t_part[i] dans une variable intemédiaire au tout début de la boucle principale, ca éviterait également des calculs pour le récupérer dans le tableau?

    Hésite pas a me coriger si jsuis a coté de la plaque

  7. #27
    Membre éclairé
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Par défaut
    Ok donc y'a encore vraiment moyen d'améliorer tout ca... Merci pour toutes ces précisions.

  8. #28
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    C'est pour ça que je me permettais de douter en te lisant...

    Citation Envoyé par vinzzzz
    ...
    Pour les autres optimisations, t'en fais pas je commence a avoir l'oeil pour éviter des calculs redondants ...


  9. #29
    Membre éclairé
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Par défaut
    L'ignorant qui s'ignore

    Mais ca fait d'autant plus plaisir d'en apprendre encore!
    En fait tous ces calculs d'adresse avec les tableau, les pointeurs etc... intuitivement j'y ait pas pensé. Et ca explique je suppose pourquoi le parcours d'une liste chainée ca prends plus de temps que celui d'un tableau.

  10. #30
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par vinzzzz
    Cette instruction:
    t_part[i]->x[j][k]
    va demander en fait a chaque fois un calcul pour obtenir t_part[i]->x[j], alors que j'aurais pu l'obtenir en une fois juste avant de rentrer dans la deuxième boucle?
    Et de la même manière, puisque j'utilise beaucoup le pointeur qui se trouve a t_part[i], si je stocke t_part[i] dans une variable intemédiaire au tout début de la boucle principale, ca éviterait également des calculs pour le récupérer dans le tableau?
    Absolument.... C'est le principe..

    Après, comme on disait plus haut, il y a d'autres choses, les structures, les avantages du langage (comme le memmove) etc... mais là déjà, sans remettre en cause la structure du programme , déjà c'est nettement plus lisible, et ensuite on a optimisé le code "hors structure"..

  11. #31
    Membre expérimenté Avatar de lun4t1k
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    276
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 276
    Par défaut
    Citation Envoyé par mujigka
    Tu as des exemples concrets... (parce que je vois pas à quel niveau il pourrait y avoir une quelconque différence)

    Thierry
    Malheureusement , ce jour là je n'ai pas noté cet algorithme.
    La seule chose que j'ai c'est que ca vient d'un prof d'algo.

    La complexité de la boucle for est calculée par la complexité du corps de cette boucle multipliée par le nombre de fois qu’elle est répétée.
    En règle générale, pour déterminer la complexité d’une boucle while, il faut avant tout déterminer le nombre de fois que cette boucle est répétée, ensuite le multiplier par la complexité du corps de cette boucle.
    Il est parfois plus difficile de compter le nombre de répétitions
    Mais d'accord qu'on analyse les boucles while comme les boucles for.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    int PGCD(int A, int B){
           int  reste;
           reste = A % B;
            while (reste !== 0)
              { 
                  A = B;
                  B = reste;
                  reste = A % B;
              }
             return(B);
    nombre de répétitions du while? pas évident sans calcul.
    le for est plus "simple", c'est peut etre un abus de langage la facon dont j'utilise le mot simple.
    Cependant j'espère m'être fait comprendre!

  12. #32
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    for(;cond est strictement equivalent a while(cond). Donc il doit y avoir les memes problemes en calcul de complexite. Ton prof parlait peut-etre d'une forme restreinte de for.

    Quant au while() (et donc le for de C), il permet l'ecriture de boucles dont on ne sait meme pas si elles se terminent ou pas. Alors evaluer le nombre de passages...

  13. #33
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut
    Citation Envoyé par souviron34
    Non, c'est parce que dans un swith il y a une seule évaluation (un seul test) et un branchement. Dans un if.else si il y a plusieurs valeurs (plusieurs else if) cela fait plusieurs évaluations.
    J'ai pas regardé d'exemple avec un compilateur récent, mais dans celui que je connais (datant de 1998), les switchs sont compilés de 2 façons différentes :
    • une suite de tests/goto (éventuellement des tests malins, du genre décrémenter la valeur et sauter si résultat nul, du genre DEC ECX / JEQ xxx / SUB ECX, 2 / JEQ yyy / ...)
    • une table de pointeurs, et utilisation de la valeur testée comme index dans cette table

    D'ailleurs en ASM, je ne voit pas comment on peut autrement. Donc si tes valeurs possibles (les différents case) ne sont pas assez regroupés, ton switch sera converti en une suite de if/else.

  14. #34
    Membre expérimenté Avatar de lun4t1k
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    276
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 276
    Par défaut
    Je ne parle pas de boucles infinies! celles ci mises a part, pour un algo qui termine, avec une complexité calculable!
    Que de critères déterministes!

  15. #35
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 398
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 398
    Par défaut
    Il arrive même que gcc fasse les tests d'un switch() par dichotomie...
    On peut faire pratiquement tout en fait.
    Même réordonner certains cases s'ils se terminent tous par un saut (mais là, j'ai des doutes sur la véritable utilité de cette manoeuvre).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #36
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par lun4t1k
    Je ne parle pas de boucles infinies! celles ci mises a part, pour un algo qui termine, avec une complexité calculables!
    Que de critères déterministes!
    Je n'ai pas parle des boucles infinies, mais de celles dont on ne sait pas si elles se terminent.

  17. #37
    Membre expérimenté Avatar de lun4t1k
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    276
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 276
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Je n'ai pas parle des boucles infinies, mais de celles dont on ne sait pas si elles se terminent.
    Et alors?

    while (reste !== 0) ou for(; reste !== 0 ; ) ne facilitent pas le calcul! alors qu'ils terminent. Mais c'est sûr que de calculer la complexité d'un algo sans preuve de terminaison...
    C'est tout ce que je voulais mettre en avant !

  18. #38
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par lun4t1k
    Et alors?

    while (reste !== 0) ou for(; reste !== 0 ; ) ne facilitent pas le calcul! alors qu'ils terminent. Mais c'est sûr que de calculer la complexité d'un algo sans preuve de terminaison...
    C'est tout ce que je voulais mettre en avant !
    La condition, c'est:
    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  19. #39
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Ulmo
    J'ai pas regardé d'exemple avec un compilateur récent, mais dans celui que je connais (datant de 1998), les switchs sont compilés de 2 façons différentes :
    • une suite de tests/goto (éventuellement des tests malins, du genre décrémenter la valeur et sauter si résultat nul, du genre DEC ECX / JEQ xxx / SUB ECX, 2 / JEQ yyy / ...)
    • une table de pointeurs, et utilisation de la valeur testée comme index dans cette table

    D'ailleurs en ASM, je ne voit pas comment on peut autrement. Donc si tes valeurs possibles (les différents case) ne sont pas assez regroupés, ton switch sera converti en une suite de if/else.
    ça fait très très longtemps que je n'ai pas fait d'assembleur, et je n'ai pas regardé comment c'était décode par le compilo, mais le principe est très simple, il me semble :

    à chaque case une valeur :
    donc normalement un jmp

    Il est certain que si c'et la deuxième manière qui est utilisée, c'est beaucoup plus rapide
    Pour la première, si c'est une valeur simple (la valeur d'un entier), il n'y a pas de différence. Par contre, dans la plupart des cas où c'est utilisé, ce n'est pas un test simple sur une valeur entière prédéfinie (une constante), mais une comparaison au minimum avec une variable, souvent plusieurs tests ensemble.

    Normalement ceci devrait être équivalent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    if ( i == 3 )
    {
    }
    else
    if ( i == 2 )
    {
    }
    else
    if ( i == 1 )
    {
    }
    Et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
       switch ( i )
        {
            case 1 : 
                 break ;
            case 2 : 
                 break ;
            case 3 :
                 break ;
        }
    Par contre , ceci ne devrait PAS être équivalent :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    if ( (j == var1) && (i == 3) )
    {
    }
    else
    if ( (j == var2) && (i == 2) )
    {
    }
    else
    if ( (j == var3) && (i == 1))
    {
    }
    et

    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
     
     switch ( i )
       {
          case 3 :
                if ( j == var3 )
                  {
                  }
                break ;
     
           case 2 :
                 if ( j == var2 )
                   {
                   }
                 break ;
     
           case 1 :
                 if ( j == var1 )
                   {
                   }
                 break ;
         }

    A mons avis....

  20. #40
    Membre expérimenté Avatar de lun4t1k
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    276
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 276
    Par défaut
    ??

Discussions similaires

  1. optimiser le code d'une fonction
    Par yanis97 dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 15/07/2005, 08h41
  2. Optimiser mon code ASP/HTML
    Par ahage4x4 dans le forum ASP
    Réponses: 7
    Dernier message: 30/05/2005, 10h29
  3. optimiser le code
    Par bibi2607 dans le forum ASP
    Réponses: 3
    Dernier message: 03/02/2005, 14h30
  4. syntaxe et optimisation de codes
    Par elitol dans le forum Langage SQL
    Réponses: 18
    Dernier message: 12/08/2004, 11h54
  5. optimisation du code et var globales
    Par tigrou2405 dans le forum ASP
    Réponses: 2
    Dernier message: 23/01/2004, 10h59

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