Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Pourquoi encore C++ ?

5 views
Skip to first unread message

jeanmar...@gmail.com

unread,
Nov 20, 2008, 4:50:48 AM11/20/08
to
Je suis prêt à accorder qu'il reste un avantage à C++ pour la
rapidité, de plus en plus marginal d'ailleurs.
Il est vrai aussi que cette avantage se paie par des temps de
développement colossaux.
Alors quelles sont les raisons de la persistence de C++ dans des
projets anciens et nouveaux ?

Je pense que la vraie raison de la persistence de C++ tient à 2
facteurs:
- 1. il y a du code hérité ("legacy"), C et C++
- 2. les mauvaises performances de nombreuses applications Java

Sur le point 2, il me semble que le problème n'est pas dû de manière
intrinsèque à Java, mais peut-être à la JVM ou à la bibliothèque
standard.
Mais surtout il me semble que le facteur "culturel" est très
important.
Beaucoup de développeurs Java n'ont pas une conscience claire de où et
comment la mémoire s'alloue et se désalloue, de où est passé le temps
CPU.
Et cela pour une raison bien simple: écrire une application Java
utilisable mais peu performante est possible sans cette conscience
claire .
Alors qu'en C/C++ c'est presque impossible.

L'exemple typique d'application où Java n'a pas percé est le
navigateur.

Mayeul

unread,
Nov 20, 2008, 10:49:12 AM11/20/08
to
Bonjour,

jeanmar...@gmail.com a �crit :
> Je suis pr�t � accorder qu'il reste un avantage � C++ pour la
> rapidit�, de plus en plus marginal d'ailleurs.

Marginal, c'est discutable. La m�me chose se fait peut-�tre en � peu
pr�s le m�me temps dans les deux langages. Mais C++ permet d'envisager
des m�thodes que Java ne permet pas (sans JNI). Et qui peuvent �tre plus
rapides.
Je suppose que cela arrive souvent en pratique.

> Il est vrai aussi que cette avantage se paie par des temps de

> d�veloppement colossaux.

> Alors quelles sont les raisons de la persistence de C++ dans des
> projets anciens et nouveaux ?
>

> Je pense que la vraie raison de la persistence de C++ tient � 2
> facteurs:
> - 1. il y a du code h�rit� ("legacy"), C et C++

C'est tout de m�me un point qui me semble important !

> - 2. les mauvaises performances de nombreuses applications Java


> Sur le point 2, il me semble que le probl�me n'est pas d� de mani�re
> intrins�que � Java, mais peut-�tre � la JVM ou � la biblioth�que
> standard.
> Mais surtout il me semble que le facteur "culturel" est tr�s
> important.
> Beaucoup de d�veloppeurs Java n'ont pas une conscience claire de o� et
> comment la m�moire s'alloue et se d�salloue, de o� est pass� le temps
> CPU.

Par nature du garbage collector, je pense qu'il n'est pas possible
d'avoir une conscience claire de o� et comment la m�moire se lib�re.
L'id�e �tant plut�t que �a ne doit pas �tre important.

> Et cela pour une raison bien simple: �crire une application Java


> utilisable mais peu performante est possible sans cette conscience
> claire .
> Alors qu'en C/C++ c'est presque impossible.
>

> L'exemple typique d'application o� Java n'a pas perc� est le
> navigateur.

Je pense qu'un avantage l�gitime de C++, c'est que ce n'est pas un
langage qu'on compile une fois pour le distribuer partout. On a besoin
d'une distribution diff�rente pour chaque plate-forme, et surtout pour
chaque environnement.

Cela implique qu'on peut int�grer un programme C++ � l'OS sur lequel il
fonctionne. On peut faire des mappings fichier/m�moire qu'on utilise
exactement comme pr�vu par l'OS. On peut se d�finir comme application
par d�faut si l'OS a cette notion. On peut d�placer et copier des
fichiers de fa�on efficace avec une API directe (il n'y a pas si
longtemps on ne pouvait pas effacer un fichier avec Java.)
On peut acc�der � la base de registre, �num�rer la liste des disques
durs disponibles et leurs partitions, mont�es ou pas, si l'OS est
d'accord. Acc�der aux APIs de p�riph�riques comme les graveurs DVD,
acc�der � la couche USB pour les t�l�phones portables et webcams.

Au moins quelques-unes de ces capacit�s finissent par �tre n�cessaires
pour un programme aussi universel qu'un navigateur. Et elles ne sont pas
du tout dans la culture 'build once, run anywhere' de Java, bien que pas
impossible en sachant chercher des biblioth�ques JNI et en ajoutant
soi-m�me ce qui manque.


Ah, et puis de fa�on plus pragmatique et sans pr�voir ce qui sera
possible dans le futur : on ne peut pas toujours exiger la pr�sence ou
l'installation d'une JVM. Mais on peut toujours compter sur un minimum
vital de biblioth�ques C/C++ sur un OS pr�cis, et mettre le reste en
bundle plus ou moins cach�.


Disclaimer : En revanche, je pr�f�re personnellement utiliser Java quand
c'est possible. Je suis bien plus efficace dans ce langage, j'ai
l'impression qu'il travaille pour moi au lieu du contraire.

--
Mayeul

jlp

unread,
Nov 23, 2008, 6:37:08 AM11/23/08
to

>> Beaucoup de développeurs Java n'ont pas une conscience claire de où et
>> comment la mémoire s'alloue et se désalloue, de où est passé le temps

>> CPU.
>
>
> Par nature du garbage collector, je pense qu'il n'est pas possible
> d'avoir une conscience claire de où et comment la mémoire se libère.
> L'idée étant plutôt que ça ne doit pas être important.
>
>
Et jusqu'à certains qui croient que le GC est capable de décider ce qui
doit être garbager sans besoin de dé-référencer!
Sur la derniere remarque, chaque JVM ( Sun, IBM,Oracle/BEA, ...) a une
multitutide de parametres qui permettent de gérer la stratégie
d'allocation et garbage. C'est là souvent que ce joue une partie de la
performance de l'application ( l'autre partie étant la (mauvaise)
qualité du code).
Message has been deleted
Message has been deleted

jlp

unread,
Nov 23, 2008, 1:00:24 PM11/23/08
to
Jean-Claude Arbaut a écrit :

> jlp wrote:
>
>>
>>>> Beaucoup de développeurs Java n'ont pas une conscience claire de où et
>>>> comment la mémoire s'alloue et se désalloue, de où est passé le temps
>>>> CPU.
>>>
>>>
>>>
>>> Par nature du garbage collector, je pense qu'il n'est pas possible
>>> d'avoir une conscience claire de où et comment la mémoire se libère.
>>> L'idée étant plutôt que ça ne doit pas être important.
>>>
>>>
>
>> Et jusqu'à certains qui croient que le GC est capable de décider ce
>> qui doit être garbager sans besoin de dé-référencer!
>
>
> Tiens, je prends le fil au passage :-) Si on a une structure de
> données assez complexe (nombreux pointeurs, éventuellement
> avec des "cycles"), est-il suffisant de "déréférencer" la ou les
> variables qui accèdent à tout ça, ou faut-il "casser" la structure ?
> (est-ce que ça change quelque chose pour le GC ?)
>
Ben non justement, il faut dé-référencer toutes les ressources.
Par exemple la fuite mémoire de débutant sont sur les Collections où le
développeur dé-référence la Collection ( le conteneur) sans
dé-référencer le contenu ( sans faire Collection.clear() par exemple).

jlp

unread,
Nov 23, 2008, 1:03:12 PM11/23/08
to
jlp a écrit :
et pour ajouter de la complexité, Java gére 4 niveaux de référence (
Strong, Soft, Weak, Phantom) avec des stratégies de Garbage différentes
pour chaque type de référence. Mais là c'est JVM editer dépendant pour
ces stratégies.

Samuel Devulder

unread,
Nov 23, 2008, 2:17:06 PM11/23/08
to
Jean-Claude Arbaut a écrit :

> Tiens, je prends le fil au passage :-) Si on a une structure de
> données assez complexe (nombreux pointeurs, éventuellement
> avec des "cycles"), est-il suffisant de "déréférencer" la ou les
> variables qui accèdent à tout ça, ou faut-il "casser" la structure ?
> (est-ce que ça change quelque chose pour le GC ?)

Oui elle sera éliminée si elle n'est plus accessible depuis nulle part...

Grossièrement le GC effectue un parcours de graphe depuis les objets
persistants (les objets présents sur la pile d'appel ou les references
static). Si ta structure complexe se trouve sur un ilot isolé non
accessible depuis ces objets "persitants" alors elle sera éliminée.

sam.

Eric Razny

unread,
Nov 23, 2008, 3:17:32 PM11/23/08
to
Le Sun, 23 Nov 2008 19:00:24 +0100, jlp a écrit :

>>> Et jusqu'à certains qui croient que le GC est capable de décider ce
>>> qui doit être garbager sans besoin de dé-référencer!
>>
>>
>> Tiens, je prends le fil au passage :-) Si on a une structure de
>> données assez complexe (nombreux pointeurs, éventuellement
>> avec des "cycles"), est-il suffisant de "déréférencer" la ou les
>> variables qui accèdent à tout ça, ou faut-il "casser" la structure ?
>> (est-ce que ça change quelque chose pour le GC ?)
>>
> Ben non justement, il faut dé-référencer toutes les ressources.
> Par exemple la fuite mémoire de débutant sont sur les Collections où le
> développeur dé-référence la Collection ( le conteneur) sans
> dé-référencer le contenu ( sans faire Collection.clear() par exemple).

Salut.
Es-tu sur?

C'est l'opposé de la réponse de Samuel Devulder
(<4929ac3a$0$27457$426a...@news.free.fr>)

Pour faire plus simple je la cite :

=====


Oui elle sera éliminée si elle n'est plus accessible depuis nulle part...

Grossièrement le GC effectue un parcours de graphe depuis les objets
persistants (les objets présents sur la pile d'appel ou les references
static). Si ta structure complexe se trouve sur un ilot isolé non
accessible depuis ces objets "persitants" alors elle sera éliminée.

=====

Si tu déréférences un Vecteur par exemple (en supposant que ses
éléments ne soient pas référencés ailleurs), on se retrouve face à
la "structure complexe sur un ilôt isolé" non?

Sinon on va finir par regretter les destructeurs du C++ qui eux sont
appelés à coup sur, contrairement au finalize ;)

Eric.

Message has been deleted

Wykaaa

unread,
Nov 23, 2008, 6:02:16 PM11/23/08
to
Jean-Claude Arbaut a écrit :
> Mayeul wrote:
>> Bonjour,
>>
>> jeanmar...@gmail.com a écrit :

>>> Je suis prêt à accorder qu'il reste un avantage à C++ pour la
>>> rapidité, de plus en plus marginal d'ailleurs.
>>
>> Marginal, c'est discutable. La même chose se fait peut-être en à peu
>> près le même temps dans les deux langages. Mais C++ permet d'envisager
>> des méthodes que Java ne permet pas (sans JNI). Et qui peuvent être
>> plus rapides.
>> Je suppose que cela arrive souvent en pratique.
>>
>>> Il est vrai aussi que cette avantage se paie par des temps de
>>> développement colossaux.

>>
>>> Alors quelles sont les raisons de la persistence de C++ dans des
>>> projets anciens et nouveaux ?
>>>
>>> Je pense que la vraie raison de la persistence de C++ tient à 2
>>> facteurs:
>>> - 1. il y a du code hérité ("legacy"), C et C++
>>
>> C'est tout de même un point qui me semble important !

>>
>>> - 2. les mauvaises performances de nombreuses applications Java
>>
>>
>>> Sur le point 2, il me semble que le problème n'est pas dû de manière
>>> intrinsèque à Java, mais peut-être à la JVM ou à la bibliothèque
>>> standard.

>>> Mais surtout il me semble que le facteur "culturel" est très
>>> important.
>>> Beaucoup de développeurs Java n'ont pas une conscience claire de où et
>>> comment la mémoire s'alloue et se désalloue, de où est passé le temps

>>> CPU.
>>
>> Par nature du garbage collector, je pense qu'il n'est pas possible
>> d'avoir une conscience claire de où et comment la mémoire se libère.
>> L'idée étant plutôt que ça ne doit pas être important.
>>
>
> Les deux ou trois premières réponses de
> http://www.google.com/search?hl=en&q=site%3Ajava.sun.com+filetype%3Apdf+garbage+collector
>
> donnent des indications intéressantes à ce sujet ;-)

Sauf que le premier lien pointe sur un pdf qui date de l'an 2000 !
(Google n'est pas la panacée...)

Il faut plutôt aller voir ici :
http://blog.xebia.fr/2008/03/12/gc-generationnels-traditionnels-jdk6-vs-gc-garbage-first-jdk7/
Ca c'est un article intéressant.
>
> "Garbage collection (GC) is probably the most widely misunderstood
> feature of the Java platform. GC is typically advertised as removing all
> memory management responsibility from the application developer. This
> just isn’t the case."

S'il n'y avait qu'en Java que le GC est mal compris. Hélas, la plupart
des développeurs ne possèdent pas la culture nécessaire pour bien
comprendre le GC.
Dans tout bon GC, il y a un mécanisme de "vieillissement" (comme dans
les OS avec machine à segmentation mémoire comme GCOS7 sur le DPS7, par
exemple) un peu semblable à celui expliqué dans la référence que j'ai
donnée plus haut.
Toute explication qui fait abstraction de ce mécanisme est sans intérêt
car celui-ci explique pourquoi il est difficile de comprendre ce que
fait réellement un GC (que ce soit celui de Java ou autre).
Il faut remarquer, en outre, que ce que doit faire réellement le GC de
la JVM ne fait pas parti des spécifications de celle-ci. Chaque JVM fait
donc, en gros, ce qui lui plaît :-)

Pour changer de sujet et revenir au sujet initial de ce fil, la
réputation de mauvaise performance de Java date des implémentations
initiales des JVM. Aujourd'hui, avec les JIT (Just In Time) compiler, il
ne doit pas y avoir de problème sauf que plus de 80% des programmeurs
Java codent comme des pieds (ou avec leurs pieds, au choix). Hélas c'est
aussi vrai (encore plus probablement) pour les programmeurs C++.

Francois

unread,
Nov 23, 2008, 6:41:39 PM11/23/08
to
Wykaaa a �crit :

> S'il n'y avait qu'en Java que le GC est mal compris. H�las, la plupart
> des d�veloppeurs ne poss�dent pas la culture n�cessaire pour bien
> comprendre le GC.

Tout ce que je sais sur le GC, c'est que d�s qu'un objet n'est plus
accessible car il n'y a plus de r�f�rence pour l'atteindre, alors cet
objet est candidat au GC, mais on ne sait pas quand exactement l'objet
sera d�truit.

Est-ce juste ? Est-il n�cessaire d'en savoir davantage ?

PS : je ne suis pas d�veloppeur loin de l�, je me contente d'apprendre
le langage Java.

--
Fran�ois

Wykaaa

unread,
Nov 23, 2008, 7:16:08 PM11/23/08
to
Francois a écrit :
> Wykaaa a écrit :

>
>> S'il n'y avait qu'en Java que le GC est mal compris. Hélas, la plupart
>> des développeurs ne possèdent pas la culture nécessaire pour bien
>> comprendre le GC.
>
> Tout ce que je sais sur le GC, c'est que dès qu'un objet n'est plus
> accessible car il n'y a plus de référence pour l'atteindre, alors cet
> objet est candidat au GC, mais on ne sait pas quand exactement l'objet
> sera détruit.
>
> Est-ce juste ?

Oui, globalement c'est juste.

Est-il nécessaire d'en savoir davantage ?

Ca dépend du type d'application, de ce qu'elle fait, etc.

Si tu as une application qui tourne 24h/24 (une appli transactionnelle
comme de la réservation de place, par exemple) et qu'elle crée des
objets, éventuellement volumineux, qui ne sont jamais libérés (parce que
le développeur aura programmé de telle façon qu'il reste toujours au
moins une référence sur les objets), cela va poser des problèmes au bout
d'un certain temps.

Ceci se produisait sous X11/Motif. Il m'arrivait de ne pas quitter ma
session pendant une semaine et au bout d'un moment, la machine ramait
parce qu'elle "swappait" sans arrêt à cause de la saturation mémoire due
à la non libération de certains objets.

>
> PS : je ne suis pas développeur loin de là, je me contente d'apprendre
> le langage Java.

Bon courage. Est-ce ton premier langage ?

Francois

unread,
Nov 23, 2008, 7:57:13 PM11/23/08
to
Wykaaa a écrit :

> Bon courage. Est-ce ton premier langage ?

Non. J'avais d'abord tenté le C, que je trouve dur, puis le Python que
j'aime bien et j'ai voulu voir le Java qui me convient bien (il me
semble) à cause de son aspect
"compilateur-qui-empêche-d'écrire-trop-de-bêtises".

Voilà.


--
François

Samuel Devulder

unread,
Nov 24, 2008, 1:17:08 AM11/24/08
to
Wykaaa a écrit :

> Pour changer de sujet et revenir au sujet initial de ce fil, la
> réputation de mauvaise performance de Java date des implémentations
> initiales des JVM. Aujourd'hui, avec les JIT (Just In Time) compiler, il
> ne doit pas y avoir de problème sauf que plus de 80% des programmeurs
> Java codent comme des pieds (ou avec leurs pieds, au choix). Hélas c'est
> aussi vrai (encore plus probablement) pour les programmeurs C++.

Le soucis est que l'algorithmique est peu comprise de la plupart des
nouveaux programmeurs. Ainsi on voit fleurir ce genre de construction:

List<E> col = ....;
for(int i = 0; i<col.size(); i++) {
E element = col.get(i);
...
}

Or si la liste est une liste dont le size() est coûteux à calculer (par
exemple parce que c'est une liste chaînée écrite à la main), on se
retrouve à avoir du code en N^2 qui ne passe pas à l'échelle. Et même
dans l'absolu si le size() prend un temps constant à calculer, il faut
voir que l'appel d'une méthode est forcément plus coûteux que l'accès à
une variable locale. Aussi il vaudrait mieux écrire:

for(int i=0, max=col.size(); i<max; ++i) {
...
}

Ce qui donnera un code un peu plus performant (tout dépend du nombre
d'itérations et de ce que l'on calcule dans la boucle).

Ça n'est qu'un exemple.. mais on le trouve vraiment partout.

sam.

TestMan

unread,
Nov 24, 2008, 4:25:39 AM11/24/08
to

Bonjour,

Ceci est faux, même s'il y a des cycles, le GC fait son taf ! C'est
justement la diférence entre un simple méchanisme de compreur de
référence (à la ObjectiveC par exemple) et un garbage collector.

Le nettoyage "à la main" est donc quasiment inutile.

Le seul effet est de suppression "en avance" les références afin de
permetre au GC de libérer plus tôt la mémoire de ces éléments (utiles
par exemple sur une grosse structure si le vecteur lui même reste
partielement utilisé par exemple).

La vrai question qui tue est : "comment le GC diférencie un cycle d'un
utilisation réelle ?" ;-)

A+
TM

Wykaaa

unread,
Nov 24, 2008, 4:59:26 AM11/24/08
to
Samuel Devulder a écrit :

> Wykaaa a écrit :
>
>> Pour changer de sujet et revenir au sujet initial de ce fil, la
>> réputation de mauvaise performance de Java date des implémentations
>> initiales des JVM. Aujourd'hui, avec les JIT (Just In Time) compiler,
>> il ne doit pas y avoir de problème sauf que plus de 80% des
>> programmeurs Java codent comme des pieds (ou avec leurs pieds, au
>> choix). Hélas c'est aussi vrai (encore plus probablement) pour les
>> programmeurs C++.
>
> Le soucis est que l'algorithmique est peu comprise de la plupart des
> nouveaux programmeurs. Ainsi on voit fleurir ce genre de construction:
>
> List<E> col = ....;
> for(int i = 0; i<col.size(); i++) {
> E element = col.get(i);
> ...
> }

Est-ce l'enseignement qui est défaillant ?

Je persiste à penser, avec 35 ans d'expérience en informatique et
l'encadrement d'équipes de développeurs de" haut niveau" (écoles
d'ingénieurs du groupe 1), qu'un programmeur qui ne maîtrise pas
l'algorithmique de base ET le langage de programmation dans lequel il
code est comme un menuisier qui ne saurait pas utiliser un rabot ou une
scie....
Autrement dit, 90% des programmeurs ne sont que des "pousseurs de
caractères" mais certainement pas des personnes adéquates pour "faire le
job".


>
> Or si la liste est une liste dont le size() est coûteux à calculer (par
> exemple parce que c'est une liste chaînée écrite à la main), on se
> retrouve à avoir du code en N^2 qui ne passe pas à l'échelle. Et même
> dans l'absolu si le size() prend un temps constant à calculer, il faut
> voir que l'appel d'une méthode est forcément plus coûteux que l'accès à
> une variable locale. Aussi il vaudrait mieux écrire:
>
> for(int i=0, max=col.size(); i<max; ++i) {
> ...
> }
>
> Ce qui donnera un code un peu plus performant (tout dépend du nombre
> d'itérations et de ce que l'on calcule dans la boucle).
>
> Ça n'est qu'un exemple.. mais on le trouve vraiment partout.
>
> sam.

Ton exemple n'est pas un problème spécifique à Java. Il est général,
même dans des langages non objets.
Un programmeur qui écrit comme ça doit être envoyé en formation ou viré
sur le champ !

Samuel Devulder

unread,
Nov 24, 2008, 11:58:38 AM11/24/08
to
Wykaaa a écrit :

> Ton exemple n'est pas un problème spécifique à Java. Il est général,
> même dans des langages non objets.

Absolument.

> Un programmeur qui écrit comme ça doit être envoyé en formation ou viré
> sur le champ !

Ca nécessiterait de reformer 99% des gens, y compris certains chez ibm :)

Sur le fond, ca dépend de la boucle et du temps qu'elle prend par
rapport au temps total. Si c'est une boucle occasionnelle, peu importe
de l'optimiser (je ne suis pas de ceux qui préconisent l'optim pour
l'optim).

Non, ce qu'il faut apprendre pour l'occasion c'est de savoir utiliser un
profiler pour trouver les goulets d'étranglement du programme plutôt que
de se trouver des excuses dans les lieux communs aujourd'hui largement
faux en disant "java ca rame" et en refusant de se remettre en cause en
examinant si on aurait par hasard pas codé de façon in-efficace ou
efficace sur des petites instances mais sans tenir compte du passage à
l'échelle.

Le jdk1.6.0_07 possède un outil sympa pour (entre autre) profiler:
jvisualvm. Savoir l'utiliser est un must à mon avis.

sam.

Wykaaa

unread,
Nov 24, 2008, 12:24:55 PM11/24/08
to
Samuel Devulder a écrit :

> Wykaaa a écrit :
>
>> Ton exemple n'est pas un problème spécifique à Java. Il est général,
>> même dans des langages non objets.
>
> Absolument.
>
>> Un programmeur qui écrit comme ça doit être envoyé en formation ou
>> viré sur le champ !
>
> Ca nécessiterait de reformer 99% des gens, y compris certains chez ibm :)

IBM, de ce point de vue, n'est pas au-dessus du lot...


>
> Sur le fond, ca dépend de la boucle et du temps qu'elle prend par
> rapport au temps total. Si c'est une boucle occasionnelle, peu importe
> de l'optimiser (je ne suis pas de ceux qui préconisent l'optim pour
> l'optim).
>
> Non, ce qu'il faut apprendre pour l'occasion c'est de savoir utiliser un
> profiler pour trouver les goulets d'étranglement du programme plutôt que
> de se trouver des excuses dans les lieux communs aujourd'hui largement
> faux en disant "java ca rame" et en refusant de se remettre en cause en
> examinant si on aurait par hasard pas codé de façon in-efficace ou
> efficace sur des petites instances mais sans tenir compte du passage à
> l'échelle.
>
> Le jdk1.6.0_07 possède un outil sympa pour (entre autre) profiler:
> jvisualvm. Savoir l'utiliser est un must à mon avis.
>
> sam.

Tout à fait d'accord. Il faut savoir utiliser les outils adéquats du
développement. Les profilers sont très importants.

Moi non plus je ne suis pas partisan de l'optimisation à tout va mais
quand on dit à un programmeur que la priorité du projet ce sont les
performances, il cherche à tout optimiser alors que la règle des 80/20
s'applique : un programme passe, en général, 80% de son temps dans 20%
du code. Ce sont ces 20% qu'il faut optimiser et c'est là que les
profilers entrent en scène pour aider à trouver ces 20%.

jlp

unread,
Nov 25, 2008, 4:47:30 PM11/25/08
to
Eric Razny a écrit :
Je reconnais que ma réponse n'est pas tout à fait exacte. C'est une
simplification hative. En fait comme dit plus bas, chaque editeur à son
propre algorithme ( Il n'y a qu'à voir comme est géré le GC des Soft
References pour chaque editeur) . Mais quand la collection devient
complexe ( Collections de Collections de ...), voire partagée par des
threads concurrents, il vaut mieux forcer le dé-référencement dans le
code dans une clause finally d'un try/catch quand le besoin est.


Quant au lien sur la derniere strtégie de Garbage ( Garbage First) elle
est encore toute récente et prometeuse pour se rapprocher du "Temps
Reel" par rapport aux strategie GC Parallel / GC Concurrent plus
ancienne.

Christian Laborde

unread,
Nov 26, 2008, 6:49:11 AM11/26/08
to
Quel est le rapport de la clause finally d'un try/catch avec la destruction d'un
objet ?

jlp a écrit :

--
Christian Laborde
La Révolution citoyenne, c'est sur : http://c.lab.over-blog.com/
Le forum des électrons libres : http://electrons-libres.forumactif.fr
True E-mail : remove -no-spam-
Sentier des Vinches
CH 1091 Grandvaux
Suisse

Mayeul

unread,
Nov 26, 2008, 9:27:47 AM11/26/08
to
Christian Laborde a écrit :
> jlp a écrit :

>> Je reconnais que ma réponse n'est pas tout à fait exacte. C'est une
>> simplification hative. En fait comme dit plus bas, chaque editeur à
>> son propre algorithme ( Il n'y a qu'à voir comme est géré le GC des
>> Soft References pour chaque editeur) . Mais quand la collection
>> devient complexe ( Collections de Collections de ...), voire partagée
>> par des threads concurrents, il vaut mieux forcer le dé-référencement
>> dans le code dans une clause finally d'un try/catch quand le besoin est.
>>
>>
>> Quant au lien sur la derniere strtégie de Garbage ( Garbage First)
>> elle est encore toute récente et prometeuse pour se rapprocher du
>> "Temps Reel" par rapport aux strategie GC Parallel / GC Concurrent
>> plus ancienne.

> Quel est le rapport de la clause finally d'un try/catch avec la

> destruction d'un objet ?

Vu que c'est ici une opération visant à libérer des ressources, ça me
semble avoir sa place dans un finally, au même titre qu'une fermeture de
stream, qu'une libération de connexion, etc. L'idée étant que ça arrive
qu'il y ait exception ou pas, et quelle que soit l'instruction "return"
atteinte.

Par contre, je suis surpris qu'il existe des GC nécessitant qu'on casse
les cycles et les structures profondes. Ça me semble aller complètement
à l'encontre du design des bibliothèques de base du langage.

--
Mayeul

jlp

unread,
Nov 30, 2008, 12:51:55 PM11/30/08
to
Mayeul a écrit :

> Christian Laborde a écrit :
>
>> jlp a écrit :
>>
>>> Je reconnais que ma réponse n'est pas tout à fait exacte. C'est une
>>> simplification hative. En fait comme dit plus bas, chaque editeur à
>>> son propre algorithme ( Il n'y a qu'à voir comme est géré le GC des
>>> Soft References pour chaque editeur) . Mais quand la collection
>>> devient complexe ( Collections de Collections de ...), voire partagée
>>> par des threads concurrents, il vaut mieux forcer le dé-référencement
>>> dans le code dans une clause finally d'un try/catch quand le besoin est.
>>>
[SNIP]

>
> Par contre, je suis surpris qu'il existe des GC nécessitant qu'on casse
> les cycles et les structures profondes. Ça me semble aller complètement
> à l'encontre du design des bibliothèques de base du langage.
>
> --
> Mayeul
Oui et je viens m'excuser ici, pour la grosse bétise que j'ai dite au
sujet du non dé-référencement des objets contenus dans une collection
quand on dé-référence directement la Collection. Et à la réflexion,
heureusement que cela marche comme cela...
Ca été signalé par 2 intervenants plus haut dans le fil.

Pour me faire pardonner, vous trouverez là un petit document issus de
tests mettant en jeu une fuite mémoire et ses correctifs, ainsi que la
preuve de ma grosse bétise.
http://pagesperso-orange.fr/jean-louis.pasturel/docs/memoryLeak.pdf

Emmanuel Bourg

unread,
Dec 4, 2008, 1:08:48 PM12/4/08
to
Samuel Devulder a écrit :

> Le soucis est que l'algorithmique est peu comprise de la plupart des
> nouveaux programmeurs. Ainsi on voit fleurir ce genre de construction:
>
> List<E> col = ....;
> for(int i = 0; i<col.size(); i++) {
> E element = col.get(i);
> ...
> }
>
> Or si la liste est une liste dont le size() est coûteux à calculer (par
> exemple parce que c'est une liste chaînée écrite à la main), on se
> retrouve à avoir du code en N^2 qui ne passe pas à l'échelle. Et même
> dans l'absolu si le size() prend un temps constant à calculer, il faut
> voir que l'appel d'une méthode est forcément plus coûteux que l'accès à
> une variable locale. Aussi il vaudrait mieux écrire:
>
> for(int i=0, max=col.size(); i<max; ++i) {
> ...
> }

Je ne sais pas si l'exemple est bien choisi, il me semble que toutes les
List du JDK mémorisent leur taille pour ne pas avoir à recompter les
éléments à chaque appel de la méthode size(). Donc ce cas précis
l'optimisation suggérée complique la syntaxe et n'apporte rien de
significatif au niveau des performances.

Samuel Devulder

unread,
Dec 4, 2008, 2:21:59 PM12/4/08
to Emmanuel Bourg
Emmanuel Bourg a écrit :

>> for(int i=0, max=col.size(); i<max; ++i) {
>> ...
>> }
>
> Je ne sais pas si l'exemple est bien choisi, il me semble que toutes les
> List du JDK mémorisent leur taille pour ne pas avoir à recompter les
> éléments à chaque appel de la méthode size(). Donc ce cas précis
> l'optimisation suggérée complique la syntaxe et n'apporte rien de
> significatif au niveau des performances.


C'est vrai. Mais comme on ne peut assumer que size() s'effectue toujours
en temps constant (chacun est libre de retourner sa propre
implementation), cette optim est bienvenue.

Comme je l'ai dit aussi cela dépend du contexte, il n'y a pas pire que
les optims pour les optims. Mais dans le cadre d'applis temps réel ou le
calcul de size() est répété de l'ordre de dizaine de millions de fois,
le fait de ne pas avoir à le calculer et s'épargner un appel à une
fonction peut faire gagner les ms qui manquaient.

Un autre cas ou j'ai vu cela est le fait qu'un algo linéaire se
comportait en N^2 en pratique. Le soucis ici était que le calcul du
size() (bien planqué dans une lib externe) était aussi couteux que
l'itération elle même. Pour trouver cela.. il a suffit d'utiliser un
échantillonnage manuel de la stacktrace de VM via le débuggeur eclipse
et de voir que 9 fois sur 10 le thread était dans size()... Si size() ne
prend pas de temps la proportion aurait du être tout autre. Pour
corriger ce défaut, il aura simplement fallu stocker la size() dans une
variable locale de la boucle.

Dans le même style, en regardant les sources du jdk ils font remarquer
que l'accès à un champ d'instance est plus long que l'accès à une
variable locale. Aussi quand cela est nécessaire, ils font une copie du
champ dans une variable locale pour gagner quelques cycles. Par ailleurs
la copie dans la variable locale permet des optimisations que le
compilateur ne peut faire quand on adresse un champ d'instance. En
effet, un champ d'instance est intrinsèquement volatile (il peut être
modifié par un autre thread) et donc sa valeur ne peut être inférée
constante. Cela est totalement d'une variable locale java qui ne peut
être modifiée à l'extérieur du bloc ou elle est définie. Le compilo peut
utiliser cela pour optimiser le code.

Bien entendu ces petites optims n'ont de sens que si elles sont répétées
des millions de fois (les petits ruisseaux).. Si on veut gagner des
ordres de grandeur il vaut mieux changer son algorithme et peut être
utiliser un peu plus de mémoire pour stocker des choses pré calculées.
En fait tout dépend de l'application et des contraintes correspondantes.

sam.

Samuel Devulder

unread,
Dec 4, 2008, 2:22:23 PM12/4/08
to
Emmanuel Bourg a écrit :

>> for(int i=0, max=col.size(); i<max; ++i) {
>> ...
>> }
>
> Je ne sais pas si l'exemple est bien choisi, il me semble que toutes les
> List du JDK mémorisent leur taille pour ne pas avoir à recompter les
> éléments à chaque appel de la méthode size(). Donc ce cas précis
> l'optimisation suggérée complique la syntaxe et n'apporte rien de
> significatif au niveau des performances.

Mayeul

unread,
Dec 5, 2008, 3:20:14 AM12/5/08
to
Samuel Devulder a écrit :

> Emmanuel Bourg a écrit :
>
>>> for(int i=0, max=col.size(); i<max; ++i) {
>>> ...
>>> }
>>
>> Je ne sais pas si l'exemple est bien choisi, il me semble que toutes
>> les List du JDK mémorisent leur taille pour ne pas avoir à recompter
>> les éléments à chaque appel de la méthode size(). Donc ce cas précis
>> l'optimisation suggérée complique la syntaxe et n'apporte rien de
>> significatif au niveau des performances.
>
>
> C'est vrai. Mais comme on ne peut assumer que size() s'effectue toujours
> en temps constant (chacun est libre de retourner sa propre
> implementation), cette optim est bienvenue.

Chacun est libre de faire sa propre implémentation, mais un size() en
temps non constant me semble être un manque flagrant de considération
pour l'usage de cette méthode. Le problème se situerait là, plus que
dans le fait de rappeler size() à chaque tour de boucle.

Après, bon, on a pas toujours la possibilité de modifier
l'implémentation fautive, et puis de toute façon un appel de méthode est
plus coûteux qu'un accès à une variable locale.

--
Mayeul

0 new messages