Détournement de topic (merci phenix ) [cours d'optimisation inside] - Java - Programmation
Marsh Posté le 25-09-2002 à 17:30:10
C'est pour obtenir le resultat en KB, le KB valant 1024 soit 2^10
Marsh Posté le 25-09-2002 à 23:27:36
ok
et pour la premeiere explication j ai bon?
Citation : usage correspond a la memoire vive utilisé par le prog? |
Marsh Posté le 25-09-2002 à 23:31:06
http://java.sun.com/j2se/1.3/docs/ [...] ntime.html
a peu pres, ouais. (Mémoire prise par la jvm) - (Memoire libre dans la jvm)
Marsh Posté le 26-09-2002 à 00:01:51
lorill a écrit a écrit : http://java.sun.com/j2se/1.3/docs/ [...] ntime.html a peu pres, ouais. (Mémoire prise par la jvm) - (Memoire libre dans la jvm) |
Marsh Posté le 26-09-2002 à 01:14:24
mais euh pq on fait pas /1024 au lieu de >>10?
Marsh Posté le 26-09-2002 à 09:02:27
--greg-- a écrit a écrit : mais euh pq on fait pas /1024 au lieu de >>10? |
Tu peux, mais le "bit shifting" est l'operation la plus rapide qu'il soit avec la comparaison avec 0.
Juste une question de performance.
Bye
Marsh Posté le 26-09-2002 à 09:50:41
phenixl a écrit a écrit : Tu peux, mais le "bit shifting" est l'operation la plus rapide qu'il soit avec la comparaison avec 0. Juste une question de performance. |
Marsh Posté le 26-09-2002 à 10:46:18
ok, bon quand j'aurai quelques neurones qui seront revenus de voyage j'essaierai de comprendre comment ça marche
Marsh Posté le 26-09-2002 à 11:11:22
ReplyMarsh Posté le 26-09-2002 à 11:12:21
tu décale le chiffre bianire de 10 => c'est comme si tu divisais 10 fois par 2 => comme si tu divisait par 10^2 => comme si tu divisais par 1024.
mais bon si ca se trouve, le compilateur repère ce genre de truc (division par une puissance de 2) et fait la modif tout seul ...
Marsh Posté le 26-09-2002 à 11:14:42
--greg-- a écrit a écrit : ok, bon quand j'aurai quelques neurones qui seront revenus de voyage j'essaierai de comprendre comment ça marche |
Simple. Imaginons un codage sur un octet (plus cout a ecrire)
00000001 = 1 = 2^0
00000010 = 2 = 2^1
00000100 = 4 = 2^2
00001000 = 8 = 2^3
...
Bon. Tu peux donc voir que quand tu decales le bit a gauche tu multiplie par 2, et si tu décale a droite tu divises par 2. C'est tout
Marsh Posté le 26-09-2002 à 11:31:52
benou a écrit a écrit : tu décale le chiffre bianire de 10 => c'est comme si tu divisais 10 fois par 2 => comme si tu divisait par 10^2 => comme si tu divisais par 1024. mais bon si ca se trouve, le compilateur repère ce genre de truc (division par une puissance de 2) et fait la modif tout seul ... |
Les bons compilo oui ...
Les tres bon font meme mieux
A*3 = a*2 + a = a << 1 + a
Marsh Posté le 26-09-2002 à 11:48:09
euh vi en fait ça j'avais compris
mais c quoi que j'avais pas compris finalement?
à ouais: qu'advient-il des bits qui tombent dans le vide?
Marsh Posté le 26-09-2002 à 11:50:01
--greg-- a écrit a écrit : à ouais: qu'advient-il des bits qui tombent dans le vide? |
plouf.
Marsh Posté le 26-09-2002 à 11:51:08
Selon le decalage utilisé, soit ils bouclent, soit ils sont perdus, soit ils changent un obscur flag dans le processeur. Avec l'operateur >> ils disparaissent tout simplement.
Marsh Posté le 26-09-2002 à 11:57:11
je vais me taper un ptit résumé des opérateurs méconnus moua
Marsh Posté le 26-09-2002 à 11:59:17
--greg-- a écrit a écrit : je vais me taper un ptit résumé des opérateurs méconnus moua |
Euh le decalage qui reinsere les bits a droite, je pense pas qu'il soit accessible via java. C'est ce qui me reste de mes cours d'asm
Marsh Posté le 26-09-2002 à 12:07:59
ca depends dans quel sens tu parles
mais je voulais bien dire reinsertion a droite apres decalage a gauche :
10100000 -> 01000001
Marsh Posté le 26-09-2002 à 14:41:06
benou a écrit a écrit : mais bon si ca se trouve, le compilateur repère ce genre de truc (division par une puissance de 2) et fait la modif tout seul ... |
De manière générale, il est déconseillé d'effectuer ce genre d'optimisations au niveau source, qui ne font que rendre plus difficile à lire le code, sans apporter de réel gain, car, comme le souligne très justement benou, la plupart des compilateurs incluent un optimiseur capable d'effectuer tout seul de telles optimisations à lucarne.
Maintenant, parlons Java. Le compilateur Java (JavaC comme Jikes) n'est pas, ou très peu, optimisant. La philosophie de Sun étant, je suppose, "on ne fait pas d'a priori sur le matériel sous-jacent quand on génère le bytecode". Vous retrouverez donc, au niveau du bytecode, la division par 1024 telle que vous l'avez écrite dans votre code source Java (d'ailleurs c'est logique d'un autre point de vue : si JavaC transformait la division par 1024 en un décalage à droite de 10 bits, on ne retrouverait pas le source original en décompilant le .class, ce qui est contraire à la philosophie de Java).
Mais de toute façon, le bytecode est lui-même interprété par la machine virtuelle, et cette dernière a la possibilité de faire l'optimisation, n'est-ce pas ? Pour le vérifier, j'ai fait un test avec mon JDK 1.4 et le code suivant :
Code :
|
> javac Test |
Pas fameux. Mais Sun fournit une machine virtuelle bien plus optimisante qu'HotSpot : HotSpot Server. Et en effet :
> javac -server Test |
(Note : sans le += dans la boucle, HotSpot Server aurait éliminé entièrement la boucle, car il aurait vu qu'elle ne servait à rien...)
Moralité : Avec HotSpot Server, oubliez la réécriture optimisante du code source. Le gain est nul, sauf en maintenabilité du code, où vous êtes perdant à tous les coups. Et quoi que vous fassiez, les optimiseurs des compilateurs, ou, ici, de la JVM, seront infiniment plus efficaces. Le pire, c'est qu'en optimisant à la main votre code source, vous risquez fort d'entraver le boulot, donc l'efficacité, de l'optimiseur...
Marsh Posté le 26-09-2002 à 14:48:19
tres interessant tout ca merci Biface
perso y a encore qq chose que je comprend pas
lorsque mon programme tourne ,la valeur de usage varie entre 4000 - et 6000
mais lorsque je regarde le gestionnaire de tache de win2k ca grimpe a 30 000 Ko parfois
pourquoi les valeurs ne correspondent pas?
Marsh Posté le 26-09-2002 à 14:50:47
veryfree a écrit a écrit : mais lorsque je regarde le gestionnaire de tache de win2k ca grimpe a 30 000 Ko parfois pourquoi les valeurs ne correspondent pas? |
parce que usage te file la mémoire prise par ton prog dans la jvm, w2k te file la mémoire prise par la jvm.
Marsh Posté le 26-09-2002 à 14:59:17
Joel F a écrit a écrit : Les bons compilo oui ... Les tres bon font meme mieux A*3 = a*2 + a = a << 1 + a |
Ce genre de trucs tu peux oublier en java... les compilos existants ne le font pas ou tres peu...
Vu qu'on parle d'optimisation je me lache un coup :
Je parlais un peu plus haut de la comparaison avec 0 : c'est pareil, on ne pense que rarement a optimiser les boucles du genre :
Code :
|
La pluspart des gens font ceci en pensant qu'ils ont optimise leur code en inlinant l'appel a la methode :
Code :
|
Alors que le code le plus efficace et rapide est :
Code :
|
Bien entendu si le but est de parcourir une STD l'ordre de parcours doit etre indifferent (on commence par la fin sinon), mais dans ce cas les temsp d'execution peuvent etre tres fortement reduits, car la comparaison avec 0 est immediate et ne demande aucun calcul.
Toujours au niveau de la performance : ca ne sert a rien de diminuer systematiquement la taille du code en inlinant certaines perties du code. Voici un exemple simple de HashTable optimise :
Si on prend une fonction de hash bien equilibree et que l'on utilise une methode de stockage efficace, la collision lors de la l'insertion dans la table doit etre exceptionnelle. Ca c'est la theorie qui le veut.
Pourtant ce que l'on voit souvent dans les hashtables perso c'est un truc du genre :
Code :
|
Dans ce cas on adopte une attitude ou on pense que "ca ne va pas marcher"... et la theorie dit "ca marche presque toujours". Il est donc bien plus interessant de faire ainsi :
Code :
|
Oui il y a plus d'operations, mais UNIQUEMENT si on se trouve dans le cas exceptionnel ou l'insertion ne marche pas du premier coup ! Le loop unroll permet dans les cas normaux de gagner ENORMEMENT en termes d'efficacite.
Juste pour donner un ordre d'idee : en deux semaines, a force de bouquiner et chercher une solution theorique qui tient la route, on a reussi a diminuer le footprint de 150% et augmenter la vitesse de pres de 200% par rapport a une HT *deja optimisee* de maniere grossiere. On a code pendant 4 jours a tout casser pour tester differentes versions de nos HT
Ah oui : le test consistait a lire et charger en memoire le bytecode de la jdk 1.3.1 en virant les redondances dues au constant pool.
Le code n'etait pas minimal, mais bon la lisibilite etait la et le resultat aussi
A+
Marsh Posté le 26-09-2002 à 15:00:58
ReplyMarsh Posté le 26-09-2002 à 15:19:45
Cherrytree a écrit a écrit : Biface toujours aussi efficace. |
une belle rime digne d'un NTM des grands jours
Marsh Posté le 26-09-2002 à 15:20:30
--greg-- a écrit a écrit : une belle rime digne d'un NTM des grands jours |
Pff... Je frappe pas les singes. Sauf Joey Starr.
Marsh Posté le 26-09-2002 à 15:31:51
BifaceMcLeOD a écrit a écrit : difficile à lire le code, sans apporter de réel gain |
Les compilos ne font que rarement des optimisations efficaces... et ne parlons meme pas de -O qui en gros ne fait que virer certains attributs du constant pool (linenumber, source file, deprecated...) et fait du inlining plus pousse.
Quant au gain je t'assure qu'utiliser le bit shift est TRES utile et te permet de gagner enormement (p.ex. travaux sur les flux video). Maintenant oui c'est moins lisible et il faut bien documenter le code... Dans certains cas c'est du "needed pain".
Citation : |
Sun n'a jamais voulu que l'on retrouve le code original a partir du bytecode apres decompilation. C'est une feature du bytecode, feature longtemps critiquee par les gens du mon C++, mais largement appreciee depuis.
Le compilo est simplement non optimisant, c'est tout (l'idee derriere etant que le JIT va faire du bon boulot, ce qui est souvent le cas, mais on peut AMELIORER ce comportement en suivant certaines regles). Oui la relecture est plus difficile, mais il faut savoir ce que l'on desire.
Pareil en C, C++, etc... Tu n'est pas oblige de faire certaines optimisations, mais tu as la possibilite de les faire, car tu sais que le compilo ne les fera jamais.
Citation : |
Tu prends un test minimaliste pour tirer des conclusions hatives :
- 100 mio d'operations ce n'est rien dans les cas ou tu fais du calcul intensif,
- ta facon de calculer le temps pris par tes operations est tres discutable : ne JAMAIS prendre System.currentTimeMillis() ! tu ne vois nullement le temps cpu exact pris par tes calculs... Un meilleur test serait de faire deux tests separes et les lancer via la commande unix "time". La tu peux comparer tes resultats (tu lances tes tests 20 fois chacuns, tu vires le bruit et tu compares)
- Enfin dire que 11ms sur un calcul aussi simple ce n'est rien me fait sourrir (c'est quand meme 3%)
Dans un contexte plus complique des optimisations faites a la main peuvent enormement faire varier les resultats : l'homme peut remettre dans un contexte particulier un probleme (cf mon post sur le loop unroll) et faire des optimisations qu'aucun JIT ne fera car a priori ce n'est pas une optimisation (le unroll est un cas bien particulier ou on s'appuie sur le contexte et non pas uniquement sur la grammaire) ou celle ci risque de modifier le sens du code (c.f. boucles inversees). C'est la qu'il faut se creuser les meninges.
Sinon oui pour les petits trucs le JIT se derbrouille bien mais pas toujours optimalement.
A+
Marsh Posté le 26-09-2002 à 15:41:25
merci infiniment phenix
vraiment tres interessant
ps: j ai renommer le topic en consequence
Marsh Posté le 26-09-2002 à 15:49:42
tiré de : http://www.club-internet.fr/encyclopedie/
phénix [feniks] n. masc. MYTH. Chez les Égyptiens, oiseau lié au culte du Soleil, dont il était l'image. Les Grecs, reprenant le mythe, firent du phénix, appelé boïnou chez les Égyptiens, un oiseau fabuleux qui, consumé dans les flammes, renaissait de ses cendres. Fig. (et souvent iron.) Personne qui a une intelligence, des capacités exceptionnelles
phenixl
Marsh Posté le 26-09-2002 à 16:22:17
par exemple : "Mais t'es un vrai phénix, toi !" (Pensées, tome 2, Cherrytree)
Marsh Posté le 26-09-2002 à 16:57:29
phenixl> Je ne tirais pas de conclusions hâtives à partir d'un exemple très simple, j'ai illustré mon propos par un exemple très simple, nuance. Et contrairement à ce que tu sembles dire, cette illustration était parfaitement judicieuse : elle a permis de montrer qu'utiliser une JVM optimisante est incroyablement plus efficace que de rajouter une petite optimisation à lucarne à la main dans son source, optimisation qui rend par ailleurs celui-ci moins compréhensible.
Maintenant, je ne dis pas qu'il ne faut jamais optimiser à la main, mais je dis que l'optimisation est une discipline qui demande rigueur, et que ce genre d'optimisation à lucarne est exactement ce qu'il ne faut pas faire. Contrairement à ce que tu dis, la plupart des compilateurs modernes ont un mode optimisant très efficace. La doc de gcc en donne une bonne idée (quoique ne sont pas détaillées les optimisations concernant, par exemple, la gestion des parcours de tableaux en utilisant des pointeurs).
Malheureusement, JavaC est le parfait contre-exemple, et Jikes ne fait pas mieux car il a été conçu pour être un clone de JavaC du point de vue comportement (mais pas vitesse d'exécution ).
Ce que je vais dire est le résultat d'études poussées sur des centaines voire des milliers de projets (ce n'est pas moi qui les ai fait, je vous rassure ) : l'optimisation manuelle est rarement bénéfique, et sans mesures préalables précises et localisées (j'insiste sur ce dernier mot), elle ne l'est quasiment jamais. D'ailleurs le nombre de programmes qui requièrent d'être vraiment optimisés sont rares, surtout en Java (au passage, remplacer un algorithme par un autre pour que le programme soit plus rapide, je n'appelle pas ça à proprement parler de l' "optimisation" ).
Il est inutile et dangereux d'optimiser son source, sans avoir préalablement mesuré très précisément quels étaient ses goulots d'étranglement. Et le seul moyen d'obtenir ces mesures précises et localisées, ce n'est :
Non, le seul outil véritablement valable, c'est le profileur, qui mesure précisément le temps d'exécution passé sur chacune des lignes de code source, et le nombre de fois qu'une ligne a été exécutée. Et souvent, un programme est lent parce qu'il a été mal conçu (mauvaise architecture), ou qu'une ou plusieurs fonctions sont appelées beaucoup trop souvent, alors qu'on pourrait garder leur résultat en mémoire entre les appels. Revoir l'architecture du programme ou appeler beaucoup moins souvent une fonction coûteuse est souvent bien plus efficace que faire une petite optimisation à lucarne dans un coin que l'on suppose souvent exécuté et/ou "trop" coûteux.
Exemples de profileurs pour Java : JProfiler, OptimizeIt, J-Sprint, ou le profileur fourni avec le J2SDK de Sun.
En C++, je n'en connais qu'un (ce qui ne veut pas dire qu'il n'y en a pas d'autre ) : Rational Quantify.
Maintenant, c'est clair que dans certaines situations, on a besoin d'avoir un programme plus rapide que ce qu'il n'est, et plus rapide que ce que le compilateur peut générer. Dans ce cas, il est tout à fait possible de réécrire quelques fonctions en assembleur (tu vois, je n'imagine même pas qu'on puisse avoir ce besoin en Java), mais ces réécritures doivent être, autant que possible, localisées, pour minimiser le coût de maintenance future, et dans tous les cas dirigées par les informations que donne le profileur. Sinon, c'est du temps de développement perdu, et beaucoup de temps supplémentaire perdu dans le futur pour la maintenance et l'évolution du logiciel.
PS: Les posts aussi longs qui ne sont pas du flood sont rares en ces lieux. Merci de m'avoir lu jusqu'au bout !
Marsh Posté le 26-09-2002 à 17:13:30
--greg-- a écrit a écrit : putain le mec qui prend4h pour écrire son post |
on ne décourage pas les bons eleves de ce forum
Marsh Posté le 26-09-2002 à 17:14:16
veryfree a écrit a écrit : on ne décourage pas les bons eleves de ce forum |
ha bah non hein, j'ai mis un justement...
Marsh Posté le 26-09-2002 à 17:27:41
veryfree a écrit a écrit : on ne décourage pas les bons eleves de ce forum |
Les bons profs, j'aurais dit.
Marsh Posté le 26-09-2002 à 17:35:02
Cherrytree a écrit a écrit : Les bons profs, j'aurais dit. |
trop tard j ai deja été quoté 2 fois
Marsh Posté le 26-09-2002 à 17:43:46
veryfree a écrit a écrit : trop tard j ai deja été quoté 2 fois |
Spagrave. Pour la peine, tu vas dire si c'est mieux un profkiroxxduluc ou un élèvekisuxxdubek.
Marsh Posté le 26-09-2002 à 17:48:53
Cherrytree a écrit a écrit : Spagrave. Pour la peine, tu vas dire si c'est mieux un profkiroxxduluc ou un élèvekisuxxdubek. |
non pitié ne detourne pas ce topic c pas c++ vs java ici
Marsh Posté le 25-09-2002 à 17:28:05
edit: pour l optimisation c un peu plus bas ds cette meme page
Message édité par veryfree le 26-09-2002 à 15:42:32