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

Dotnet Discussion :

Les Break dans les boucles


Sujet :

Dotnet

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 266
    Points : 135
    Points
    135
    Par défaut Les Break dans les boucles
    Bonjour à tous,

    Ma question n'est pas comment utiliser les BREAK mais quel en est la performence dans l'utilisation des BREAK dans les boulce de type FOREACH ?

    J'ai souvant entendu que l'utilisation des break dans les boulce de type FOREACH était déconceillé pour une question de performence.

    Merci de m'éclairer la dessus.

  2. #2
    Rédacteur
    Avatar de The_badger_man
    Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    2 745
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 745
    Points : 8 538
    Points
    8 538
    Par défaut
    Ha, les break dans les boucles foreach...
    Qu'est-ce qu'on ferait pas pour éviter une boucle do/while. Si mon ancienne prof d'algo voyait ça....

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Février 2003
    Messages
    191
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 191
    Points : 158
    Points
    158
    Par défaut
    Exactement, la première chose qu'on m'a apprise en algo, c'est de ne jamais utiliser de break . Si tu veux faire des itérations personnalisées, va voir du côté du design pattern Iterator...

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 652
    Points : 730
    Points
    730
    Par défaut
    Citation Envoyé par pc152
    J'ai souvant entendu que l'utilisation des break dans les boulce de type FOREACH était déconceillé pour une question de performence.
    C'est nouveau ça...

    Citation Envoyé par Royd938
    Exactement, la première chose qu'on m'a apprise en algo, c'est de ne jamais utiliser de break
    Ça aussi...

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 266
    Points : 135
    Points
    135
    Par défaut
    Maniak il serait bien d'argumenter et pas seulement de mettre deux mots

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 652
    Points : 730
    Points
    730
    Par défaut
    Citation Envoyé par pc152
    Maniak il serait bien d'argumenter et pas seulement de mettre deux mots
    Argumenter je veux bien, mais c'est pas moi qui ait le plus à argumenter là.

    Pour break/continue : ça peut rendre les boucles plus claires et éviter des tests inutiles.

    Contre break/continue : la prof d'algo a dit que c'était pas bien.


    Donc question : en quoi est-ce que ce n'est pas bien au juste ? Ce ne sont pas des gotos, et à moins d'avoir des boucles de 2 pages de long, ça n'a que du positif sur la lisibilité.


    Ça fait un peu plus que deux mots là non ? :)
    Mais pour en faire plus, faudrait que je sache au juste ce qui est reproché à break/continue. Là tout de suite ça m'interpelle quelque part.

  7. #7
    Membre habitué Avatar de apokrif
    Inscrit en
    Novembre 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 120
    Points : 192
    Points
    192
    Par défaut
    Citation Envoyé par Maniak
    Donc question : en quoi est-ce que ce n'est pas bien au juste ? Ce ne sont pas des gotos, et à moins d'avoir des boucles de 2 pages de long, ça n'a que du positif sur la lisibilité.
    Je crois que l'objectif est de rassembler toutes les conditions d'arrêt en un seul point (la condition du for ou du while).

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 652
    Points : 730
    Points
    730
    Par défaut
    Citation Envoyé par apokrif
    Je crois que l'objectif est de rassembler toutes les conditions d'arrêt en un seul point (la condition du for ou du while).
    Oui justement. Ça c'était la règle du temps où on considérait que des boucles de 10 pages sont vivables. Parce que là, quand il y avait 10 points de sortie, c'était le boxon.

    Vu que depuis la règle est devenue de ne pas faire de boucle de 10 pages, et plus généralement de faire des méthodes courtes et claires, ce n'est plus un problème. Au contraire, persister à n'avoir qu'un point de sortie peut rendre le code plus difficile à lire, avec tests et indentations inutiles, alors qu'un simple break/continue suffirait à simplifier tout ça.
    Et vu que ces boucles tiennent en quelques lignes, aucun risque de se perdre en route.

    C'est comme de persister à faire des tests qui englobent tout le contenu d'une méthode pour ne rien faire si une certaine condition n'est pas remplie, juste pour ne pas mettre un return.
    Si la méthode est longue, complexe et que sortir en cours de route pose des risques, ok, c'est pas une bonne idée. Mais la solution est de découper la méthode, pas de bannir des instructions utiles pour de mauvaises raisons.

  9. #9
    Membre du Club
    Inscrit en
    Janvier 2005
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 63
    Points : 60
    Points
    60
    Par défaut
    En algo on t'apprends un truc:
    • Si tu dois boucler tant que une condition est vraie, tu utilise un while
    • Si tu dois boucler de toutes facons dans toute ta collection, utilise un for
    Ce n'est pas pour rien. Mais pour une question de lisibilite et de standard et d'education (rigueur). C'est aussi valable que les standard de codes de Microsoft. C'est fait pour que un developpeur X qui connait les regles MS de codage arrive dans une boite Y et ne passe pas 5 heures a comprendre une classe...

    Moi je applique des regles basiques d'algo (telle que celles la) toujours et je le fais appliquer a mon equipe. Resultat, quand un developpeur regarde mon code, il comprend ce que je veux faire...

    Par contre, pour le soucis de perf, j'ai jamais lu ca...

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 652
    Points : 730
    Points
    730
    Par défaut
    Citation Envoyé par leMarseillais
    En algo on t'apprends un truc:
    • Si tu dois boucler tant que une condition est vraie, tu utilise un while
    • Si tu dois boucler de toutes facons dans toute ta collection, utilise un for
    Ce n'est pas pour rien. Mais pour une question de lisibilite et de standard et d'education (rigueur). C'est aussi valable que les standard de codes de Microsoft. C'est fait pour que un developpeur X qui connait les regles MS de codage arrive dans une boite Y et ne passe pas 5 heures a comprendre une classe... :yaisse2:
    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
    public class Toto : IList<Titi>
    {
      ...
     
      public Titi FindById( int id )
      {
        foreach ( Titi item in this )
        {
          if ( item.Id.Equals( id ) ) return item;
        }
        return null;
      }
     
      public Titi FindById2( int id )
      {
        Titi result = null;
        int index = 0;
        while ( result == null && index < this.Count )
        {
          if ( this[ index ].Id.Equals( id ) ) result = this[ index ];
          ++index;
        }
        return result;
      }
    }
    Ou plus drôle :
    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
    public bool HasDuplicates( Titi[] items1, Titi[] items2 )
    {
      foreach ( Titi item1 in items1 )
      {
        foreach ( Titi item2 in items2 )
        {
          if ( item1.Equals( item2 ) ) return true;
        }
      }
      return false;
    }
     
    public bool HasDuplicates2( Titi[] items1, Titi[] items2 )
    {
      bool result = false;
      int index1 = 0;
      while ( !result && index1 < items1.Length )
      {
        int index2 = 0;
        while ( !result && index2 < items2.Length )
        {
          if ( items1[index1].Equals( items2[index2] ) ) result = true;
          ++index2;
        }
        ++index1;
      }
      return result;
    }
    Même principe avec des breaks si les boucles font partie d'une autre méthode.
    (j'ai grapillé quelques lignes pour l'affichage, donc c'est mal présenté là :)

    Il faut combien d'heures pour comprendre chaque, et laquelle est la plus lisible ?
    Laquelle a le plus de chances d'avoir des erreurs d'inattention, d'oublier d'incrémenter un index, de mal faire un test, tout ça ?

    Il y aurait 2 pages de code dans la boucle avec des return/break/continue perdus au milieu pour certaines conditions, ok, ce serait innommable. Mais 2 pages de code dans une boucle est déjà innommable.

    Dans une boucle de quelques lignes, indiquer clairement ce qu'on veut faire (si on a trouvé une valeur, on coupe, si telle condition est remplie, on ignore l'élément, ...) plutôt que rajouter des compteurs, des booléens de sortie etc, c'est à la fois plus clair, plus lisible, plus compréhensible et plus logique.

    Les règles d'algo toutes faites c'est bien, mais il faut voir le contexte. Les règles qui s'appliquent dans 100% des cas sans la moindre exception, ça ne court pas les rues.

  11. #11
    Membre du Club
    Inscrit en
    Janvier 2005
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 63
    Points : 60
    Points
    60
    Par défaut
    Tes arguments sont tout a fait valides, mais n'empeche que tes foreach me font mal aux yeux et les while me paraissent plus logique, mais c'est surement par habitude, ce qui est un parametre que personne n'a nomme !

    Maintenant reste a savoir si il y a un soucis de performance avec le foreach enonce en debut de sujet dont je n'ai jamais entendu parler.

    Par exemple, si tu return dans ton foreach, que se passe-t-il avec les objects enumerateurs (c'est une vraie question, je sais pas la reponse)?

    Il me semble que tu controles mieux les objects avec un while, car tu peut mieux clean up les ressources, mais dependant de la reponse a la question precedente cette affirmation peut etre inutile

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 652
    Points : 730
    Points
    730
    Par défaut
    Citation Envoyé par leMarseillais
    Maintenant reste a savoir si il y a un soucis de performance avec le foreach enonce en debut de sujet dont je n'ai jamais entendu parler.
    Aucun.
    break et continue sautent juste à la fin de l'itération, et return sort juste de la méthode, sans aucun effet secondaire particulier.
    Si tu fais un gros if qui englobe tout le traitement d'une itération, ça revient *strictement* au même. C'est juste plus lourd à écrire, ça ajoute un niveau d'indentation, quand ça n'ajoute pas de nouvelles variables ne servant *que* pour se souvenir qu'il ne faut pas exécuter le reste de l'itération.

    Si on n'a plus besoin d'exécuter le reste de l'itération, c'est tellement plus clair et simple de dire 'continue'. Si on n'a plus besoin de poursuivre la boucle, c'est tellement plus clair et simple de dire 'break'. Ce sont quand même des termes on ne peut plus clairs pour indiquer l'intention du code. Et écrire clairement l'intention du code est toujours une bonne idée :)
    C'est pas comme si break et continue étaient des goto dont le rôle est toujours un grand mystère :)

    Citation Envoyé par leMarseillais
    Par exemple, si tu return dans ton foreach, que se passe-t-il avec les objects enumerateurs (c'est une vraie question, je sais pas la reponse)?
    Ben c'est un objet comme un autre. Il n'est plus référencé et il passe dans le garbage collector quand il en aura envie.

    Un foreach, ce n'est jamais qu'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    IEnumerator enumerator = items.GetEnumerator();
    while ( enumerator.MoveNext() )
    {
      Toto item = enumerator.Current as Toto;
      ...
    }
    (sans le cast en passant par les versions génériques)

    Donc toi qui préfère les while... :)

    Citation Envoyé par leMarseillais
    Il me semble que tu controles mieux les objects avec un while, car tu peut mieux clean up les ressources, mais dependant de la reponse a la question precedente cette affirmation peut etre inutile
    :mouarf:
    Justement, il n'y a aucune ressource particulière à nettoyer avec un foreach. C'est une bête simplification d'écriture, avec comme seul 'lourdeur' supplémentaire le passage par un énumérateur. Sauf que c'est tellement mineur que dans 99.9% des cas, la différence est inexistante. Il ne reste que l'écriture simplifiée :)

  13. #13
    Membre du Club
    Inscrit en
    Janvier 2005
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 63
    Points : 60
    Points
    60
    Par défaut

    D'accord, dans ce cas tu as raison. Mais c'est dur de changer les habitudes de plusieurs annees de formation de cerveau algorithmique...

    Mais les habitudes sont faites pour etre changees, merci pour ces eclaircissements!

Discussions similaires

  1. enlever les slashes devant les apostrophes dans les mails
    Par laurentSc dans le forum Langage
    Réponses: 10
    Dernier message: 16/11/2010, 18h57
  2. Réponses: 3
    Dernier message: 06/08/2009, 17h09
  3. les classes et les templates dans les plugins
    Par asoka13 dans le forum C++
    Réponses: 22
    Dernier message: 24/01/2008, 17h11
  4. Réponses: 4
    Dernier message: 11/09/2006, 16h55
  5. Les polices dans les tables et les requêts
    Par zooffy dans le forum Access
    Réponses: 3
    Dernier message: 21/06/2006, 11h06

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