|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||||
|
Nouveau Membre du Club
![]() Inscription : octobre 2008 Messages : 61 ![]() |
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 :
Code :
|
||||
|
|
00
|
|
|
#2 |
![]() ![]() R&D en systemes informatiques bas niveau Unix/Linux Inscription : mai 2004 Messages : 7 168 ![]() |
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. |
|
|
10
|
|
|
#3 |
|
Nouveau Membre du Club
![]() Inscription : octobre 2008 Messages : 61 ![]() |
Je vais suivre ton conseil. Je posterai mes conclusions
|
|
|
00
|
|
|
#4 |
|
Expert Confirmé Sénior
![]() Inscription : janvier 2007 Messages : 9 569 ![]() |
en dehors de ce qu'a dit gangsoleil, il faut tenir compte aussi de plusieurs choses :
__________________
"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 |
|
|
10
|
|
|
#5 |
|
Membre éprouvé
![]() Gilles Inscription : août 2011 Messages : 169 ![]() |
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. |
|
|
10
|
|
|
#6 | |
![]() ![]() R&D en systemes informatiques bas niveau Unix/Linux Inscription : mai 2004 Messages : 7 168 ![]() |
Citation:
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. |
|
|
|
11
|
|
|
#7 | |
|
Membre éprouvé
![]() Gilles Inscription : août 2011 Messages : 169 ![]() |
Citation:
Ca c'est pour la forme. Sur le fond : j'ai parlé de tests complexes, merci de bien lire... |
|
|
|
01
|
|
|
#8 | ||
![]() ![]() R&D en systemes informatiques bas niveau Unix/Linux Inscription : mai 2004 Messages : 7 168 ![]() |
Citation:
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:
|
||
|
|
11
|
|
|
#9 | |
|
Expert Confirmé
![]() Tlouye Ci Inscription : mars 2004 Messages : 1 800 ![]() |
Citation:
Et c'est d'autant plus vrai dans les langages Objet qui permettent la surcharge des méthodes. |
|
|
|
01
|
|
|
#10 | |
|
Membre éprouvé
![]() Gilles Inscription : août 2011 Messages : 169 ![]() |
Citation:
|
|
|
|
11
|
|
|
#11 |
|
Expert Confirmé Sénior
![]() Inscription : décembre 2007 Messages : 2 541 ![]() |
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. |
|
|
00
|
|
|
#12 | ||
|
Expert Confirmé Sénior
![]() Inscription : janvier 2007 Messages : 9 569 ![]() |
Citation:
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
Citation:
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 |
||
|
|
00
|
|
|
#13 |
|
Nouveau Membre du Club
![]() Inscription : octobre 2008 Messages : 61 ![]() |
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. |
|
|
10
|
|
|
#14 |
|
Nouveau Membre du Club
![]() Inscription : octobre 2008 Messages : 61 ![]() |
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... |
|
|
20
|
|
|
#15 |
|
Expert Confirmé Sénior
![]() Inscription : janvier 2007 Messages : 9 569 ![]() |
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 |
|
|
10
|
|
|
#16 |
|
Membre éprouvé
![]() Gilles Inscription : août 2011 Messages : 169 ![]() |
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. |
|
|
11
|
Copyright © 2000-2013 - www.developpez.com