Précédent   Forum du club des développeurs et IT Pro > Général Développement > Langages de programmation
Langages de programmation Forum général sur les langages de programmation, sur la POO, opinions, choix, ...
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 07/11/2012, 21h50   #1
DavidleVrai
Nouveau Membre du Club
 
Inscription : octobre 2008
Messages : 61
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 61
Points : 30
Points : 30
Par défaut Sortie anticipée d'une boucle. "break"

Bonjour la communauté de developpez.

Ma question est simple mais je n'ai pas trouvé de réponse sérieuse sur le net.
L'utilisation d'un "break" est elle judicieuse où faut il privilégier les conditions de sortie dans un while ?

Exemple en Java avec break :
Code :
1
2
3
4
5
6
7
int val = 9;
int tab[] = {1, 2, 6, 5, 2, 1, 9, 8, 1, 5};
int i = 0;
while (i<tab.lenght()) {
	if (tab[i] != val) { break; }
	i++;
}
Exemple en Java avec une condition de sortie :
Code :
1
2
3
4
5
6
int val = 9;
int tab[] = {1, 2, 6, 5, 2, 1, 9, 8, 1, 5};
int i = 0;
while ((i<tab.lenght()) && (tab[i] != val)) {
	i++;
}
DavidleVrai est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/11/2012, 09h04   #2
gangsoleil
Modérateur
 
Avatar de gangsoleil
 
R&D en systemes informatiques bas niveau Unix/Linux
Inscription : mai 2004
Messages : 7 168
Détails du profil
Informations personnelles :
Âge : 32
Localisation : France, Isère (Rhône Alpes)

Informations professionnelles :
Activité : R&D en systemes informatiques bas niveau Unix/Linux

Informations forums :
Inscription : mai 2004
Messages : 7 168
Points : 17 956
Points : 17 956
Bonjour,

Ca va dependre de ton architecture, et de la complexite reelle de ta boucle.

Dans le cas que tu montres, le code genere doit etre a peu pres pareil ; pour verifier, ecris ce programme en C, et regarde le code assembleur genere.

Par contre, si tu as un vrai traitement dans ta boucle, ca peut changer un peu. Dans le premier cas, tu as deux tests consecutifs. Donc si on prend un processeur de type Sparc, qui charge les instructions 4 par 4, tu vas pouvoir faire les deux tests en un seul chargement.
Par contre, si tes deux tests sont "eloignes", cela peut impliquer plus de sauts dans le code assembleur.

Bien sur, sur une boucle avec 4 occurences, on s'en fou. Je pense ici a des boucles qui seraient appelees des millions de fois ou plus.
__________________
Modérateur "C", "Informatique Générale & Hardware" et "Unix"
Les règles du forum
gangsoleil est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 09/11/2012, 06h47   #3
DavidleVrai
Nouveau Membre du Club
 
Inscription : octobre 2008
Messages : 61
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 61
Points : 30
Points : 30
Je vais suivre ton conseil. Je posterai mes conclusions .
DavidleVrai est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/11/2012, 11h36   #4
souviron34
Expert Confirmé Sénior
 
Inscription : janvier 2007
Messages : 9 569
Détails du profil
Informations personnelles :
Âge : 55

Informations forums :
Inscription : janvier 2007
Messages : 9 569
Points : 11 849
Points : 11 849
en dehors de ce qu'a dit gangsoleil, il faut tenir compte aussi de plusieurs choses :
  • Il est possible qu'il y a ait un certain nombre de conditions, certaines ne pouvant être évaluées que à l'intérieur de la boucle..

  • Si le code figurant dans la boucle comporte des algos un tant soit peu complexes, ou pas mal de tests ou de ifs imbriqués, il est plus aisé de faire des "break" que d'ajouter des niveaux d'indentation... Sans compter les gains de temps de tests inutiles...

  • Toutes ces conditions sont également valables pour les "continue" aussi.
__________________
"Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

Consultant indépendant.
Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
C, Fortran, XWindow/Motif, Java

Je ne réponds pas aux MP techniques
souviron34 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 13/11/2012, 11h57   #5
GPPro
Membre éprouvé
 
Homme Gilles
Inscription : août 2011
Messages : 169
Détails du profil
Informations personnelles :
Nom : Homme Gilles
Localisation : France, Isère (Rhône Alpes)

Informations forums :
Inscription : août 2011
Messages : 169
Points : 450
Points : 450
Tu peux aussi boucler sur un flag. Le flag étant mis à jour par chacun des tests présents dans le corps de ta boucle. Cette solution peut te sauver la vie lorsque tu es en présence d'Ayatollah anti-break

Edit : je complète ma réponse après avoir étudié plus en détail tes exemples.

Dans "Clean Code", un bouquin que tu devrais vraiment lire si tu t'intéresses à tout ce qui est approche "propre" du codage, l'auteur suggère de remplacer les tests complexes par des appels de méthodes. Ca a selon lui l'avantage de simplifier la compréhension du code.
Tu remplaces un test complexe par un appel de méthode avec un nom explicite décrivant le test en question.
GPPro est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 13/11/2012, 13h24   #6
gangsoleil
Modérateur
 
Avatar de gangsoleil
 
R&D en systemes informatiques bas niveau Unix/Linux
Inscription : mai 2004
Messages : 7 168
Détails du profil
Informations personnelles :
Âge : 32
Localisation : France, Isère (Rhône Alpes)

Informations professionnelles :
Activité : R&D en systemes informatiques bas niveau Unix/Linux

Informations forums :
Inscription : mai 2004
Messages : 7 168
Points : 17 956
Points : 17 956
Citation:
Envoyé par GPPro Voir le message
Dans "Clean Code", un bouquin que tu devrais vraiment lire si tu t'intéresses à tout ce qui est approche "propre" du codage, l'auteur suggère de remplacer les tests complexes par des appels de méthodes. Ca a selon lui l'avantage de simplifier la compréhension du code.
Tu remplaces un test complexe par un appel de méthode avec un nom explicite décrivant le test en question.
Je n'ai pas lu ce livre, et je ne souhaite pas troller dessus, mais pour une boucle appelee des millions de fois (boucle infinie de serveur, ...), un appel de methode n'a pas du tout le meme cout que le teste d'une variable.

En gros, pour tester une valeur, on charge la valeur dans un registre, on charge la valeur attendue dans un autre, et on regarde si les deux ont la meme valeur. Et si la valeur testee est 0, il n'y a pas besoin du second chargement, car 0 est souvent stockee dans un registre "en dur" sur pas mal d'architectures.

Un appel de methode, c'est beaucoup plus complexe, puisqu'outre la modification des registres, on va modifier le pointeur d'appel -- au grand minimum.
__________________
Modérateur "C", "Informatique Générale & Hardware" et "Unix"
Les règles du forum
gangsoleil est déconnecté   Envoyer un message privé Réponse avec citation 11
Vieux 13/11/2012, 13h39   #7
GPPro
Membre éprouvé
 
Homme Gilles
Inscription : août 2011
Messages : 169
Détails du profil
Informations personnelles :
Nom : Homme Gilles
Localisation : France, Isère (Rhône Alpes)

Informations forums :
Inscription : août 2011
Messages : 169
Points : 450
Points : 450
Citation:
Envoyé par gangsoleil Voir le message
Je n'ai pas lu ce livre, et je ne souhaite pas troller dessus, mais pour une boucle appelee des millions de fois (boucle infinie de serveur, ...), un appel de methode n'a pas du tout le meme cout que le teste d'une variable.

En gros, pour tester une valeur, on charge la valeur dans un registre, on charge la valeur attendue dans un autre, et on regarde si les deux ont la meme valeur. Et si la valeur testee est 0, il n'y a pas besoin du second chargement, car 0 est souvent stockee dans un registre "en dur" sur pas mal d'architectures.

Un appel de methode, c'est beaucoup plus complexe, puisqu'outre la modification des registres, on va modifier le pointeur d'appel -- au grand minimum.
Je m'attendais à ce genre de réponse, vraiment bizarre... Ou comment rejeter un principe générique au nom d'une optimisation pour un cas particulier.

Ca c'est pour la forme.

Sur le fond : j'ai parlé de tests complexes, merci de bien lire...
GPPro est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 13/11/2012, 16h05   #8
gangsoleil
Modérateur
 
Avatar de gangsoleil
 
R&D en systemes informatiques bas niveau Unix/Linux
Inscription : mai 2004
Messages : 7 168
Détails du profil
Informations personnelles :
Âge : 32
Localisation : France, Isère (Rhône Alpes)

Informations professionnelles :
Activité : R&D en systemes informatiques bas niveau Unix/Linux

Informations forums :
Inscription : mai 2004
Messages : 7 168
Points : 17 956
Points : 17 956
Citation:
Envoyé par GPPro Voir le message
Je m'attendais à ce genre de réponse, vraiment bizarre... Ou comment rejeter un principe générique au nom d'une optimisation pour un cas particulier.
Le sujet parle de savoir si un break dans un while est mieux ou pire qu'un test dans le while.
A mon sens, on est ici dans des optimisations tres fines, pas dans des cas bourrins ou il y a 42 parametres differents a interpoler avant de connaitre la valeur a tester.

Et ce cas d'optimisation fines, tu vois cela comme un cas particulier, moi c'est mon quotidien. Donc non, ce n'est pas forcement un cas particulier. Et comme on n'a pas le contexte, on ne sait pas qui de nous deux a raison, si tant est que l'un de nous deux soit plus proche du contexte du posteur que l'autre, ce qui n'est pas certain du tout.

Citation:
Sur le fond : j'ai parlé de tests complexes, merci de bien lire...
C'est quoi un test complexe ? Dans les exemples ici, on a la longueur d'un tableau, et l'acces au contenu d'une cellule.
__________________
Modérateur "C", "Informatique Générale & Hardware" et "Unix"
Les règles du forum
gangsoleil est déconnecté   Envoyer un message privé Réponse avec citation 11
Vieux 14/11/2012, 09h57   #9
Loceka
Expert Confirmé
 
Avatar de Loceka
 
Tlouye Ci
Inscription : mars 2004
Messages : 1 800
Détails du profil
Informations personnelles :
Nom : Tlouye Ci

Informations forums :
Inscription : mars 2004
Messages : 1 800
Points : 2 918
Points : 2 918
Citation:
Envoyé par gangsoleil Voir le message
A mon sens, on est ici dans des optimisations tres fines, pas dans des cas bourrins ou il y a 42 parametres differents a interpoler avant de connaitre la valeur a tester.
Et même dans ce cas-là, quand on boucle sur suffisament d'éléments, un appel de méthode se fait très nettement ressentir et peut être un facteur d'optimisation intéressant (même si c'est au détriment d'un peu de lisibilité dans le code).

Et c'est d'autant plus vrai dans les langages Objet qui permettent la surcharge des méthodes.
Loceka est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 14/11/2012, 10h23   #10
GPPro
Membre éprouvé
 
Homme Gilles
Inscription : août 2011
Messages : 169
Détails du profil
Informations personnelles :
Nom : Homme Gilles
Localisation : France, Isère (Rhône Alpes)

Informations forums :
Inscription : août 2011
Messages : 169
Points : 450
Points : 450
Citation:
Envoyé par Loceka Voir le message
Et même dans ce cas-là, quand on boucle sur suffisament d'éléments, un appel de méthode se fait très nettement ressentir et peut être un facteur d'optimisation intéressant (même si c'est au détriment d'un peu de lisibilité dans le code).

Et c'est d'autant plus vrai dans les langages Objet qui permettent la surcharge des méthodes.
Et on inventa le mot clé "inline", les macros, etc... Si vraiment vous voulez jouer au jeu des optimisations à tout prix, il y a des outils pour ça, mais bref, ce débat est à la limite du trolling.
GPPro est déconnecté   Envoyer un message privé Réponse avec citation 11
Vieux 14/11/2012, 10h35   #11
el_slapper
Expert Confirmé Sénior
 
Inscription : décembre 2007
Messages : 2 541
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 2 541
Points : 6 144
Points : 6 144
Réponse d'ingénieur : ça dépend.

(mais là, je ne fais que résumer ce qui précède).

La première chose à faire, c'est de se renseigner sur les normes de là ou tu codes. certains banniront le break ou le goto, d'autre l'autoriseront sous conditions. J'ai par exemple vu une boite ou le seul GO TO autorisé était le GO TO finDeParagraphe. une espèce de break façon cobol, quoi.

(1)Si le break est autorisé, et systématiquement utilisé, la réponse est simple : à Rome comme les Romains.

(2)Si le Break est interdit, la réponse est tout aussi simple : à Florence comme les Florentins.

(3)Si le break est autorisé, mais pas systématiquement utilisé, là, il faut faire preuve d'analyse.
==>Dans ce cas précis, je dirais que la boucle a pour seul objet d'arriver à sa condition de sortie; il me parait donc judicieux de garder la condition de sortie explicite dans la boucle elle-même, donc de ne pas mettre de break.
==>Dans le cas le plus fréquent(enfin, dans mon monde), qui est celui d'avoir une boucle qui fait des choses à chaque itération, en plus de vérifier les conditions de sortie, rajouter un break quand on arrive prématurément à un niveau ou on a plus besoin de boucler me parait plus "léger" que d'encombrer la condition de sortie.

Mais c'est juste une question de point de vue perso. Il y aura sans doute des avis divergents. Le plus important, c'est de respecter le style local. Mieux vaut un mauvais style uniformément utilisé, qu'un mélange de bons styles incompatibles(cette dernière phrase va sans doute me valoir des -1. Mais je parle d'expérience sur des codes de 36 ans d'âge).
__________________
Les 4 règles d'airain du développement informatique sont, d'après Michael C. Kasten :
1)on ne peut pas établir un chiffrage tant qu'on a pas finalisé la conception
2)on ne peut pas finaliser la conception tant qu'on a pas complètement compris toutes les exigences
3)le temps de comprendre toutes les exigences, le projet est terminé
4)le temps de terminer le projet, les exigences ont changé
Et le serment de non-allégiance :
Je promets de n’exclure aucune idée sur la base de sa source mais de donner toute la considération nécessaire aux idées de toutes les écoles ou lignes de pensées afin de trouver celle qui est la mieux adaptée à une situation donnée.
el_slapper est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2012, 11h22   #12
souviron34
Expert Confirmé Sénior
 
Inscription : janvier 2007
Messages : 9 569
Détails du profil
Informations personnelles :
Âge : 55

Informations forums :
Inscription : janvier 2007
Messages : 9 569
Points : 11 849
Points : 11 849
Citation:
Envoyé par GPPro Voir le message
Tu remplaces un test complexe par un appel de méthode avec un nom explicite décrivant le test en question.
Citation:
Envoyé par GPPro Voir le message
Sur le fond : j'ai parlé de tests complexes, merci de bien lire...
Je crois que l'on dévie, ou que la question initiale n'est pas très claire..

La règle de conduite à tenir pour les boucles, ou les while().. est d'avoir une condition simple..

Si la condition est complexe, c'est qu'il y a un problème d'analyse...

Des tests complexes ne dovent pas exister pour une boucle ..

Si c'était le cas, c'est sûr que l'appel à une méthode serait bien mieux. Cependant le fond est conceptuellement incorrect...


Maintenant, le problème du "break" est entièrement différent de la condition.. Et toalement différent également du goto

  • Le goto termine nécesairement par du code spaghetti... peut être utilisé à diverses sauces, et dans 99.99% des cas ne se justifie pas..

  • le break est une manière simple et rapide de terminer une boucle, point final (comme le "continue" est une manière simple et rapide de sauter un élément).


Citation:
Envoyé par el_slapper Voir le message
(3)Si le break est autorisé, mais pas systématiquement utilisé, là, il faut faire preuve d'analyse.
==>Dans le cas le plus fréquent(enfin, dans mon monde), qui est celui d'avoir une boucle qui fait des choses à chaque itération, en plus de vérifier les conditions de sortie, rajouter un break quand on arrive prématurément à un niveau ou on a plus besoin de boucler me parait plus "léger" que d'encombrer la condition de sortie.
Totalement d'accord...

Le fond du problème n'est pas que les conditions puissent être complexes, c'est que le code peut le devenir, avec des séries de ifs imbriqués...

Ajouter un "break" ou un "continue" simplifie et le code et la pensée et l'éxécution : on peut boucler jusqu'à une certaine limite, sauter des éléments dans certains cas, sortir dans d'autres, et c'est clair et lisible.. Faire une condition complexe est lourd, incompréhensible, peu souple, et peu efficace en termes d'optimisation justement...
__________________
"Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

Consultant indépendant.
Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
C, Fortran, XWindow/Motif, Java

Je ne réponds pas aux MP techniques
souviron34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2012, 21h15   #13
DavidleVrai
Nouveau Membre du Club
 
Inscription : octobre 2008
Messages : 61
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 61
Points : 30
Points : 30
Je n'ai pas eu le temps de faire une analyse du code assembleur comme je voulais faire. En ce moment je n'ai vraiment pas le temps...

Ma question n'était pas assez claire, je confirme.

A l'origine je m'intéressais uniquement à la performance du code. Les exemples de code que je donne ne sont pas significatifs. C'était pour me faire comprendre. Et, avec des continus ou des breaks, peut importe, le problème reste le même je pense.

En terme d'efficacité pure, j'ai toujours imaginé que de mettre des breaks était un peu pénalisant. Mais, avec des codes qui ont de nombreux if, while... imbriqués, comme les automates notamment, ça devient très vite fastidieux et en plus on obtient un code vraiment illisible. C'est pour ça que je pose cette question sur la perte d'efficacité du code lorsqu'on utilise des breaks ou des continus.

Pour participer au débat, je pense que si la rapidité du code n'est pas primordial il ne faut pas se priver des breaks, voir même il faut les utiliser, car avec on programme plus vite et un code plus clair. Les GO TO, c'est un autre problème, c'est une source d'erreur.
DavidleVrai est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 14/11/2012, 21h29   #14
DavidleVrai
Nouveau Membre du Club
 
Inscription : octobre 2008
Messages : 61
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 61
Points : 30
Points : 30
Par ailleurs plutôt que de faire une analyse du code assembleur généré, j'essaierai de faire des codes représentatifs, avec et sans breaks. Sur des boucles relativement longues je comparerai leurs temps d'exécution.

Après il faut que je trouve les codes qui seront représentatifs.

A suivre...
DavidleVrai est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 15/11/2012, 01h15   #15
souviron34
Expert Confirmé Sénior
 
Inscription : janvier 2007
Messages : 9 569
Détails du profil
Informations personnelles :
Âge : 55

Informations forums :
Inscription : janvier 2007
Messages : 9 569
Points : 11 849
Points : 11 849
Ahhhhhhhh .. Encore un qui veut optimiser en tentant d'optimiser des ifs et des breaks !!!!!!!

Disons que si c'est dans un but d'optimisation, il y a bien d'autres choses à optimiser avant ça...

Ne serait-ce que dans ton exemple..

Tab[i] représente une addition et une multiplication par élément i : i*taille+offset

Si tu utilises un pointeur, tu réduis à 1 addition par élément, tu économises donc N multiplications dans ta boucle...

C'est très nettement plus optimisant que de vouloir optimiser des ifs ou des breaks...

De manière primordiale, c'est l'algo qui doit être optimisé.

Ensuite, le genre de ce que je mentionne : utilisation de pointeurs pour enlever les calculs d'adressage; factorisation de ce qui peut l'être aux niveaux supérieurs, etc etc..

L'optimisation des ifs et breaks arrivent en toute toute toute dernière position, et n'a qu'un impact purement négligeable par rapport au reste.. Les CPU, et es compilateurs, font un boulot quasi-parfait de ce côté là... Tu peux toujours tenter, mais tu ne gagneras rien.. C'est dans le reste que tu gagnes..
__________________
"Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

Consultant indépendant.
Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
C, Fortran, XWindow/Motif, Java

Je ne réponds pas aux MP techniques
souviron34 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 15/11/2012, 06h27   #16
GPPro
Membre éprouvé
 
Homme Gilles
Inscription : août 2011
Messages : 169
Détails du profil
Informations personnelles :
Nom : Homme Gilles
Localisation : France, Isère (Rhône Alpes)

Informations forums :
Inscription : août 2011
Messages : 169
Points : 450
Points : 450
De plus, la dernière fois que je me suis intéressé à la question, et c'était y'a longtemps hein, parcourir un tableau ça se faisait avec un for (d'un point de vue perf, vous jetez pas sur le -1)...
Les compilos savent optimiser for + tableau, while + tableau je ne pense pas.

De même, pour le coup je ne pense pas que les compilateurs sachent optimiser convenablement les boucles contenant des instructions de rupture de flot. De même pour les processeurs actuels d'ailleurs.
GPPro est déconnecté   Envoyer un message privé Réponse avec citation 11
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 01h18.


 
 
 
 
Partenaires

Hébergement Web