> Il me semble que ça ne marche pas (erreur au link).
// Il s'agit du fichier projet principal pour le projet d'application VC++
// généré en utilisant un Assistant Application.
#include "stdafx.h"
#using <mscorlib.dll>
#using <system.xml.dll>
using namespace System;
using namespace System::Xml;
int _tmain()
{
System::Xml::XmlDocument *p = new System::Xml::XmlDocument() ;
p->LoadXml("<test/>") ;
Console::WriteLine(S"Hello World");
return 0;
}
ca compile, ça link, ça s'execute.
c'est un projet console C++ Managé de base.
si ça roule pas, c'est ton Vs qui pete un cable.
> J'ai un problème : (VS .NET pour C++), la complétion ne fonctionne pas
bien.
pourtant, dans certaines "formes" d'écritures, elle marche à merveille.
il faudrait etre plus precis sur ce qui se passe.
> J'ai vaguement l'impression que mon IDE est dans les choux.
possible
> Oui, mais mon appli ne fait pas que ça : elle traite de la vidéo
image/image
> (après mes accès xml en initialisation). Le fait que j'utilise le
> ne va t'il pas ralentir le reste de l'application (qui n'en a pas
?
managé ne veux pas dire perfs pitoyables. si tu n'as pas confiance, sépare
les deux mondes. écrit toi une classe __gc d'interfacage, une classe
pour l'implantation de l'autre. le beurre et l'argent du beurre.
ensuite, amuses toi à comparer en rendant ta classe d'implantation __gc.
et utilises dedans des std::vector, std::toutcequetuveux, histoire de
tu peux aussi regarder du côté du code generé et comparer.
profite en pour t'appuyer sur un profiler. ça permet de ne pas tirer de
conclusions (trop) erronées sur ce qui pompe du temps, et ça peut
à comprendre ce qui change, et ce qui ne change pas avec le concept des
classes managées (__gc)
> Franchement, le garbage collector, je sais m'en passer.
cette phrase a un parfum de testosterone :o)
les Cmens n'ont pas besoin d'objet, et d'un compilateur qui vérifie les
types, ils savent blabla blabla blabla etc.
bon, l'objet est infiniment superieur. considere que le gc est un apport
formel du même ordre.
> > l'unicité du langage ? bof. apprendre le C#, ça prend 20 minutes pour
> > gars qui connait l'Objet.
> Oui oui, c# semble très "sain". Un peu java sur les bords. Je ne m'en
plains
> pas
c'est clair. et avec ce qui va arriver (genre les generics), ça va devenir
de plus en plus interessant.
> le pointeur sur la structure de pointeurs qui identifient une table de
> fonctions qui retournent un pointeur (void).
> ...j'ai donné !
:o)
> Par contre le portage c#->c++ (non managé) ne me semble pas trivial...
bof. pourtant, ça me semble assez "direct" comme traduction. mais c'est
pareil, il faut exprimer ce que tu souhaites voir et ce que tu ne souhaite
pas voir comme bonnes propriétés dans le resultat. si c'est transformer
seul des Algos NP en Algos P, je sais pas si on peut encore appeller ça du
portage.
mais pourquoi porter quand on peut utiliser directement ? qu'est ce qui
écrit en C# et qui ne te conviens pas ?
tu as des fonctionalités en C# qui tournent trop lentement ? le but de la
manoeuvre, c'est que chacun écrit dans son langage preferé et hop,
interoperabilité. du multi culturel.
pour ma part, je ne trouve pas le C# si lent que ça. j'ai des optims qui
tournent plein pot et qui sont écrites en C#. ça a certaines vertus, faire
des objets. par exemple celle de ne pas occuper la machine a faire des
copies en pagaille. mais bon, la encore, faut profiler au cas par cas.
> Qu'est ce que "mono" ? (pardon si idiot)
c'est l'implantation sous Unix du Framework. dans l'avenir (s'il est
clément), le ciel sera radieu, et comme Java, les exe .Net d'une machine
tourneront sur une autre sans se soucier de rien. voila. Arnaud ou
pourraient t'en dire un peu plus.
je te conseille vivement d'aller jetter un oeil sur le forum
microsoft.public.fr.dotnet.
voila voila.
> Il me semble que ça ne marche pas (erreur au link).
// Il s'agit du fichier projet principal pour le projet d'application VC++
// généré en utilisant un Assistant Application.
#include "stdafx.h"
#using <mscorlib.dll>
#using <system.xml.dll>
using namespace System;
using namespace System::Xml;
int _tmain()
{
System::Xml::XmlDocument *p = new System::Xml::XmlDocument() ;
p->LoadXml("<test/>") ;
Console::WriteLine(S"Hello World");
return 0;
}
ca compile, ça link, ça s'execute.
c'est un projet console C++ Managé de base.
si ça roule pas, c'est ton Vs qui pete un cable.
> J'ai un problème : (VS .NET pour C++), la complétion ne fonctionne pas
bien.
pourtant, dans certaines "formes" d'écritures, elle marche à merveille.
il faudrait etre plus precis sur ce qui se passe.
> J'ai vaguement l'impression que mon IDE est dans les choux.
possible
> Oui, mais mon appli ne fait pas que ça : elle traite de la vidéo
image/image
> (après mes accès xml en initialisation). Le fait que j'utilise le
> ne va t'il pas ralentir le reste de l'application (qui n'en a pas
?
managé ne veux pas dire perfs pitoyables. si tu n'as pas confiance, sépare
les deux mondes. écrit toi une classe __gc d'interfacage, une classe
pour l'implantation de l'autre. le beurre et l'argent du beurre.
ensuite, amuses toi à comparer en rendant ta classe d'implantation __gc.
et utilises dedans des std::vector, std::toutcequetuveux, histoire de
tu peux aussi regarder du côté du code generé et comparer.
profite en pour t'appuyer sur un profiler. ça permet de ne pas tirer de
conclusions (trop) erronées sur ce qui pompe du temps, et ça peut
à comprendre ce qui change, et ce qui ne change pas avec le concept des
classes managées (__gc)
> Franchement, le garbage collector, je sais m'en passer.
cette phrase a un parfum de testosterone :o)
les Cmens n'ont pas besoin d'objet, et d'un compilateur qui vérifie les
types, ils savent blabla blabla blabla etc.
bon, l'objet est infiniment superieur. considere que le gc est un apport
formel du même ordre.
> > l'unicité du langage ? bof. apprendre le C#, ça prend 20 minutes pour
> > gars qui connait l'Objet.
> Oui oui, c# semble très "sain". Un peu java sur les bords. Je ne m'en
plains
> pas
c'est clair. et avec ce qui va arriver (genre les generics), ça va devenir
de plus en plus interessant.
> le pointeur sur la structure de pointeurs qui identifient une table de
> fonctions qui retournent un pointeur (void).
> ...j'ai donné !
:o)
> Par contre le portage c#->c++ (non managé) ne me semble pas trivial...
bof. pourtant, ça me semble assez "direct" comme traduction. mais c'est
pareil, il faut exprimer ce que tu souhaites voir et ce que tu ne souhaite
pas voir comme bonnes propriétés dans le resultat. si c'est transformer
seul des Algos NP en Algos P, je sais pas si on peut encore appeller ça du
portage.
mais pourquoi porter quand on peut utiliser directement ? qu'est ce qui
écrit en C# et qui ne te conviens pas ?
tu as des fonctionalités en C# qui tournent trop lentement ? le but de la
manoeuvre, c'est que chacun écrit dans son langage preferé et hop,
interoperabilité. du multi culturel.
pour ma part, je ne trouve pas le C# si lent que ça. j'ai des optims qui
tournent plein pot et qui sont écrites en C#. ça a certaines vertus, faire
des objets. par exemple celle de ne pas occuper la machine a faire des
copies en pagaille. mais bon, la encore, faut profiler au cas par cas.
> Qu'est ce que "mono" ? (pardon si idiot)
c'est l'implantation sous Unix du Framework. dans l'avenir (s'il est
clément), le ciel sera radieu, et comme Java, les exe .Net d'une machine
tourneront sur une autre sans se soucier de rien. voila. Arnaud ou
pourraient t'en dire un peu plus.
je te conseille vivement d'aller jetter un oeil sur le forum
microsoft.public.fr.dotnet.
voila voila.
> Il me semble que ça ne marche pas (erreur au link).
// Il s'agit du fichier projet principal pour le projet d'application VC++
// généré en utilisant un Assistant Application.
#include "stdafx.h"
#using <mscorlib.dll>
#using <system.xml.dll>
using namespace System;
using namespace System::Xml;
int _tmain()
{
System::Xml::XmlDocument *p = new System::Xml::XmlDocument() ;
p->LoadXml("<test/>") ;
Console::WriteLine(S"Hello World");
return 0;
}
ca compile, ça link, ça s'execute.
c'est un projet console C++ Managé de base.
si ça roule pas, c'est ton Vs qui pete un cable.
> J'ai un problème : (VS .NET pour C++), la complétion ne fonctionne pas
bien.
pourtant, dans certaines "formes" d'écritures, elle marche à merveille.
il faudrait etre plus precis sur ce qui se passe.
> J'ai vaguement l'impression que mon IDE est dans les choux.
possible
> Oui, mais mon appli ne fait pas que ça : elle traite de la vidéo
image/image
> (après mes accès xml en initialisation). Le fait que j'utilise le
> ne va t'il pas ralentir le reste de l'application (qui n'en a pas
?
managé ne veux pas dire perfs pitoyables. si tu n'as pas confiance, sépare
les deux mondes. écrit toi une classe __gc d'interfacage, une classe
pour l'implantation de l'autre. le beurre et l'argent du beurre.
ensuite, amuses toi à comparer en rendant ta classe d'implantation __gc.
et utilises dedans des std::vector, std::toutcequetuveux, histoire de
tu peux aussi regarder du côté du code generé et comparer.
profite en pour t'appuyer sur un profiler. ça permet de ne pas tirer de
conclusions (trop) erronées sur ce qui pompe du temps, et ça peut
à comprendre ce qui change, et ce qui ne change pas avec le concept des
classes managées (__gc)
> Franchement, le garbage collector, je sais m'en passer.
cette phrase a un parfum de testosterone :o)
les Cmens n'ont pas besoin d'objet, et d'un compilateur qui vérifie les
types, ils savent blabla blabla blabla etc.
bon, l'objet est infiniment superieur. considere que le gc est un apport
formel du même ordre.
> > l'unicité du langage ? bof. apprendre le C#, ça prend 20 minutes pour
> > gars qui connait l'Objet.
> Oui oui, c# semble très "sain". Un peu java sur les bords. Je ne m'en
plains
> pas
c'est clair. et avec ce qui va arriver (genre les generics), ça va devenir
de plus en plus interessant.
> le pointeur sur la structure de pointeurs qui identifient une table de
> fonctions qui retournent un pointeur (void).
> ...j'ai donné !
:o)
> Par contre le portage c#->c++ (non managé) ne me semble pas trivial...
bof. pourtant, ça me semble assez "direct" comme traduction. mais c'est
pareil, il faut exprimer ce que tu souhaites voir et ce que tu ne souhaite
pas voir comme bonnes propriétés dans le resultat. si c'est transformer
seul des Algos NP en Algos P, je sais pas si on peut encore appeller ça du
portage.
mais pourquoi porter quand on peut utiliser directement ? qu'est ce qui
écrit en C# et qui ne te conviens pas ?
tu as des fonctionalités en C# qui tournent trop lentement ? le but de la
manoeuvre, c'est que chacun écrit dans son langage preferé et hop,
interoperabilité. du multi culturel.
pour ma part, je ne trouve pas le C# si lent que ça. j'ai des optims qui
tournent plein pot et qui sont écrites en C#. ça a certaines vertus, faire
des objets. par exemple celle de ne pas occuper la machine a faire des
copies en pagaille. mais bon, la encore, faut profiler au cas par cas.
> Qu'est ce que "mono" ? (pardon si idiot)
c'est l'implantation sous Unix du Framework. dans l'avenir (s'il est
clément), le ciel sera radieu, et comme Java, les exe .Net d'une machine
tourneront sur une autre sans se soucier de rien. voila. Arnaud ou
pourraient t'en dire un peu plus.
je te conseille vivement d'aller jetter un oeil sur le forum
microsoft.public.fr.dotnet.
voila voila.
>> managé ne veux pas dire perfs pitoyables. si tu n'as pas confiance,
les deux mondes. écrit toi une classe __gc d'interfacage, une classe
normale
pour l'implantation de l'autre. le beurre et l'argent du beurre.
Ce n'est pas l'ensemble du projet qui est "managé" ?
ensuite, amuses toi à comparer en rendant ta classe d'implantation __gc.
et utilises dedans des std::vector, std::toutcequetuveux, histoire de
voir.
tu peux aussi regarder du côté du code generé et comparer.
profite en pour t'appuyer sur un profiler. ça permet de ne pas tirer de
conclusions (trop) erronées sur ce qui pompe du temps, et ça peut
contribuer
à comprendre ce qui change, et ce qui ne change pas avec le concept des
classes managées (__gc)
Je suis convaincu pour l'objet et pour une structuration "forte".
Par contre, le garbage collector, pour l'instant, je trouve que c'est un
gadget dont je peux me passer.
Pire, je trouve ce concept un peu "anti structuré" : une "construction"
avoir un pendant : la "destruction". Même si c'est une opinion de
Pour moi, j'ai remarqué que quand le développeur(se) "sait" détruire et
qu'il "laisse la mémoire dans l'état ou il la trouvée en entrant", c'est
signe de robustesse du code.
Je pense que le multi plate forme est un avantage (trolltech ?).
Le multi-langage, moins. Enfin, pour moi... Je vais peut être changer.
mais pourquoi porter quand on peut utiliser directement ? qu'est ce qui
écrit en C# et qui ne te conviens pas ?
rien. Je trouve que c'est un peu propriétaire, c'est tout.
Si mono (que je découvre) fonctionne, mon argument ne veut plus rien dire.
Je ne connais de C# que des tutoriels. Pas ses performances.
Je suppose que c'est du "super vb", sans le mot "basic" qui a fait vomir
tant de gourous.
Bref de l'interprété ou du semi inteprété genre pascal/delphi (PCode).
D'expérience, je trouve que de l'interprété bien écrit est beaucoup plus
efficace que du compilé natif bordelique.
quel profiler utilises tu ?
je te conseille vivement d'aller jetter un oeil sur le forum
microsoft.public.fr.dotnet.
j'y vais.
>> managé ne veux pas dire perfs pitoyables. si tu n'as pas confiance,
les deux mondes. écrit toi une classe __gc d'interfacage, une classe
normale
pour l'implantation de l'autre. le beurre et l'argent du beurre.
Ce n'est pas l'ensemble du projet qui est "managé" ?
ensuite, amuses toi à comparer en rendant ta classe d'implantation __gc.
et utilises dedans des std::vector, std::toutcequetuveux, histoire de
voir.
tu peux aussi regarder du côté du code generé et comparer.
profite en pour t'appuyer sur un profiler. ça permet de ne pas tirer de
conclusions (trop) erronées sur ce qui pompe du temps, et ça peut
contribuer
à comprendre ce qui change, et ce qui ne change pas avec le concept des
classes managées (__gc)
Je suis convaincu pour l'objet et pour une structuration "forte".
Par contre, le garbage collector, pour l'instant, je trouve que c'est un
gadget dont je peux me passer.
Pire, je trouve ce concept un peu "anti structuré" : une "construction"
avoir un pendant : la "destruction". Même si c'est une opinion de
Pour moi, j'ai remarqué que quand le développeur(se) "sait" détruire et
qu'il "laisse la mémoire dans l'état ou il la trouvée en entrant", c'est
signe de robustesse du code.
Je pense que le multi plate forme est un avantage (trolltech ?).
Le multi-langage, moins. Enfin, pour moi... Je vais peut être changer.
mais pourquoi porter quand on peut utiliser directement ? qu'est ce qui
écrit en C# et qui ne te conviens pas ?
rien. Je trouve que c'est un peu propriétaire, c'est tout.
Si mono (que je découvre) fonctionne, mon argument ne veut plus rien dire.
Je ne connais de C# que des tutoriels. Pas ses performances.
Je suppose que c'est du "super vb", sans le mot "basic" qui a fait vomir
tant de gourous.
Bref de l'interprété ou du semi inteprété genre pascal/delphi (PCode).
D'expérience, je trouve que de l'interprété bien écrit est beaucoup plus
efficace que du compilé natif bordelique.
quel profiler utilises tu ?
je te conseille vivement d'aller jetter un oeil sur le forum
microsoft.public.fr.dotnet.
j'y vais.
>> managé ne veux pas dire perfs pitoyables. si tu n'as pas confiance,
les deux mondes. écrit toi une classe __gc d'interfacage, une classe
normale
pour l'implantation de l'autre. le beurre et l'argent du beurre.
Ce n'est pas l'ensemble du projet qui est "managé" ?
ensuite, amuses toi à comparer en rendant ta classe d'implantation __gc.
et utilises dedans des std::vector, std::toutcequetuveux, histoire de
voir.
tu peux aussi regarder du côté du code generé et comparer.
profite en pour t'appuyer sur un profiler. ça permet de ne pas tirer de
conclusions (trop) erronées sur ce qui pompe du temps, et ça peut
contribuer
à comprendre ce qui change, et ce qui ne change pas avec le concept des
classes managées (__gc)
Je suis convaincu pour l'objet et pour une structuration "forte".
Par contre, le garbage collector, pour l'instant, je trouve que c'est un
gadget dont je peux me passer.
Pire, je trouve ce concept un peu "anti structuré" : une "construction"
avoir un pendant : la "destruction". Même si c'est une opinion de
Pour moi, j'ai remarqué que quand le développeur(se) "sait" détruire et
qu'il "laisse la mémoire dans l'état ou il la trouvée en entrant", c'est
signe de robustesse du code.
Je pense que le multi plate forme est un avantage (trolltech ?).
Le multi-langage, moins. Enfin, pour moi... Je vais peut être changer.
mais pourquoi porter quand on peut utiliser directement ? qu'est ce qui
écrit en C# et qui ne te conviens pas ?
rien. Je trouve que c'est un peu propriétaire, c'est tout.
Si mono (que je découvre) fonctionne, mon argument ne veut plus rien dire.
Je ne connais de C# que des tutoriels. Pas ses performances.
Je suppose que c'est du "super vb", sans le mot "basic" qui a fait vomir
tant de gourous.
Bref de l'interprété ou du semi inteprété genre pascal/delphi (PCode).
D'expérience, je trouve que de l'interprété bien écrit est beaucoup plus
efficace que du compilé natif bordelique.
quel profiler utilises tu ?
je te conseille vivement d'aller jetter un oeil sur le forum
microsoft.public.fr.dotnet.
j'y vais.
managé ne veux pas dire perfs pitoyables. si tu n'as pas confiance,
sépareles deux mondes. écrit toi une classe __gc d'interfacage, une classe
normale
pour l'implantation de l'autre. le beurre et l'argent du beurre.
bon, tu vas me dire c'est peut être pas aussi simple que cela. et
dans tous
les cas, je n'ai aucune preuve absolue que c'est pareil. tu ne peux
que
constater empiriquement que les mesures de perfs sont tres voisines.
ensuite, amuses toi à comparer en rendant ta classe d'implantation
__gc.
et utilises dedans des std::vector, std::toutcequetuveux, histoire
de
voir.
Je suis convaincu pour l'objet et pour une structuration "forte".
moi aussi.
l'efficacité ? il a été montré qu'un garbage collector ameliore
l'efficacité
d'un processus. eh oui, tirer la chasse d'eau une fois prends moins
de temps
que tirer la chasse d'eau un petit peu des millions de fois. le cout
de
préparation du paquet à balancer est moindre au total, parait il. en
clair,
c'est rentable.
pour faire une comparaison, écrire les delete, c'est comme écrire du
code
toutes les 3 lignes pour provoquer soit même le swap vers un autre
processus. ça fait perdre du temps à l'execution, ça prend une place
monstrueuse, ça donne au code une charge supplémentaire, et
conceptuellement, l'idée est naze. mieux vaut laisser un agent
systeme faire
le taf. ça existe déja pour les pages et le swap,
managé ne veux pas dire perfs pitoyables. si tu n'as pas confiance,
sépare
les deux mondes. écrit toi une classe __gc d'interfacage, une classe
normale
pour l'implantation de l'autre. le beurre et l'argent du beurre.
bon, tu vas me dire c'est peut être pas aussi simple que cela. et
dans tous
les cas, je n'ai aucune preuve absolue que c'est pareil. tu ne peux
que
constater empiriquement que les mesures de perfs sont tres voisines.
ensuite, amuses toi à comparer en rendant ta classe d'implantation
__gc.
et utilises dedans des std::vector, std::toutcequetuveux, histoire
de
voir.
Je suis convaincu pour l'objet et pour une structuration "forte".
moi aussi.
l'efficacité ? il a été montré qu'un garbage collector ameliore
l'efficacité
d'un processus. eh oui, tirer la chasse d'eau une fois prends moins
de temps
que tirer la chasse d'eau un petit peu des millions de fois. le cout
de
préparation du paquet à balancer est moindre au total, parait il. en
clair,
c'est rentable.
pour faire une comparaison, écrire les delete, c'est comme écrire du
code
toutes les 3 lignes pour provoquer soit même le swap vers un autre
processus. ça fait perdre du temps à l'execution, ça prend une place
monstrueuse, ça donne au code une charge supplémentaire, et
conceptuellement, l'idée est naze. mieux vaut laisser un agent
systeme faire
le taf. ça existe déja pour les pages et le swap,
managé ne veux pas dire perfs pitoyables. si tu n'as pas confiance,
sépareles deux mondes. écrit toi une classe __gc d'interfacage, une classe
normale
pour l'implantation de l'autre. le beurre et l'argent du beurre.
bon, tu vas me dire c'est peut être pas aussi simple que cela. et
dans tous
les cas, je n'ai aucune preuve absolue que c'est pareil. tu ne peux
que
constater empiriquement que les mesures de perfs sont tres voisines.
ensuite, amuses toi à comparer en rendant ta classe d'implantation
__gc.
et utilises dedans des std::vector, std::toutcequetuveux, histoire
de
voir.
Je suis convaincu pour l'objet et pour une structuration "forte".
moi aussi.
l'efficacité ? il a été montré qu'un garbage collector ameliore
l'efficacité
d'un processus. eh oui, tirer la chasse d'eau une fois prends moins
de temps
que tirer la chasse d'eau un petit peu des millions de fois. le cout
de
préparation du paquet à balancer est moindre au total, parait il. en
clair,
c'est rentable.
pour faire une comparaison, écrire les delete, c'est comme écrire du
code
toutes les 3 lignes pour provoquer soit même le swap vers un autre
processus. ça fait perdre du temps à l'execution, ça prend une place
monstrueuse, ça donne au code une charge supplémentaire, et
conceptuellement, l'idée est naze. mieux vaut laisser un agent
systeme faire
le taf. ça existe déja pour les pages et le swap,
> Mauvais plan sur la comète! Le marshalling entre les couches
managées et non managées est très inefficace! En plus, ...
<snip/> de nouveaux développements.
Deux petites remarques supplémentaires sur cet aspect :
- Actuellement, le compilateur C++ managé optimise mieux <snip/>
- Le compilateur JIT actuel n'optimise absolument pas pour le processeur
cible. Théoriquement, il est possible de faire un compilateur JIT qui
optimise le code pour la machine d'exécution <snip/>.
Mais qu'est ce qu'elle t'as fait la STL? Elle t'a traumatisée quand tu
étais petit ? ;-) Rien que pour la "type safety" qu'elle offre, je préfère
de loin la STL!
Je mettrais cependant un bémol : l'objet c'est très bien et même
indispensable, mais ca ne couvre pas tous les besoins et ce n'est pas la
solution universelle (philosophiquement, je me méfie toujours des
solutions universelles ;-) Et le problème du .NET, c'est qu'il ne t'offre
pas d'autres paradigmes de programmation et restreint donc tes choix.
C++ est multi-paradigme et laisse plus de liberté (y compris celle de se
tirer dans le pied, c'est vrai).
A titre d'exemple, la programmation générique est en plein essort dans le
monde du C++ et on commence à peine à découvrir les possibilités qu'elle
offre - et non, les génériques de C# 2.0 ne permettent pas de faire de la
programmation générique, loin s'en faut!
Non, c'est faux.
Tout ce qui a été montré, c'est que <snip/>
- Avec un GC, l'allocation est plus rapide (on incrémente un compteur au
lieu de parcourir une liste chainée).
- Avec un GC, la désallocation est moins rapide (il faut parcourir
l'arborescence des références au lieu d'insérer un maillon dans une liste
chainée, plus la surcharge système de l'arrêt/synchronisation de tous les
threads du processus)
- Avec une gestion classique, <snip/>
mais le défaut c'est qu'on risque
d'avoir des "pauses" dans l'exécution du programme (pendant que le
GC tourne, tous les threads de l'appli sont bloqués), alors qu'avec
des destructions tout au long du fil du
programme, le temps passé dans ces destructions est "lissé" sur toute la
durée d'exécution.
C'est typiquement très visible en Java. Je dois
reconnaitre que c'est nettement moins perceptible en .NET : je suppose que
c'est lié essentiellement au mécanisme générationnel du GC .NET. Dans tous
les cas, ca rend bien sûr les GC inapliquables si on a des contraintes
temprs réel fortes - ce qui est rare j'en conviens.
Ceci dit, indépendamment de toutes ces considérations d'accro au
performances qui n'ont généralement pas beaucoup d'intérêt pratique, le GC
tel que proposé en .NET présente à mon avis 2 énormes défauts :
- l'idiome RAII (Ressource Acquisition Is Initialization) est
innapliquable<snip/>
- la séparation "les classes complexes sont allouées sur le tas et gérées
par le GC et les types primitifs et les objets simples (struct) sont
alloués sur la pile" est ridicule et n'a pas de sens du point de vue de la
conception objet pure. On peut très bien avoir besoin localement dans une
fonction d'un objet complexe (de par son arbre d'héritage, sa taille ou
autre), et il n'y a pas de raison de ne pas pouvoir l'allouer sur la pile.
.NET offre déjà une amélioration de ce point de vue par rapport à Java
grâce aux structs et au boxing/unboxing automatique, mais on n' a pas
encore la souplesse du C++ (au fait, toi qui te plaint des copies cachées
en C++, le > boxing/unboxing entraine des copies de l'objet!)
??? tu peux expliquer en quoi écrire un delete ressemble à "swapper vers
un> autre processus" (ce qui ne veut rien dire en soi...) ? Je te
qu'écrire un delete, ce n'est pas que libérer de la mémoire, c'est avant
tout appeler un destructeur (logiquement, c'est bien plus important).
Au passage, dans du code C++ *bien écrit*, il n'y a pas (ou très peu) de
delete.
On utilise RAII ! Je vois (et ponds) régulièrement du code C++ de
plus de 10000 ligne sans un seul delete dans le code utilisateir.
En ce qui concerne la taille "monstrueuse" (tu as des chiffres?) du code
de destruction des objets généré par le C++, c'est vrai que ce code prend
la place, mais :
- le GC aussi prend de la place :-)
- le code de destructions C++ fait partie du déroulement normal du
programme et bénéficie donc des effets de cache et de pipeline sur le
processeur. Par contre, quand le GC se déclenche, tu es bon à tous
les coups pour vider le <snip/>
> Mauvais plan sur la comète! Le marshalling entre les couches
managées et non managées est très inefficace! En plus, ...
<snip/> de nouveaux développements.
Deux petites remarques supplémentaires sur cet aspect :
- Actuellement, le compilateur C++ managé optimise mieux <snip/>
- Le compilateur JIT actuel n'optimise absolument pas pour le processeur
cible. Théoriquement, il est possible de faire un compilateur JIT qui
optimise le code pour la machine d'exécution <snip/>.
Mais qu'est ce qu'elle t'as fait la STL? Elle t'a traumatisée quand tu
étais petit ? ;-) Rien que pour la "type safety" qu'elle offre, je préfère
de loin la STL!
Je mettrais cependant un bémol : l'objet c'est très bien et même
indispensable, mais ca ne couvre pas tous les besoins et ce n'est pas la
solution universelle (philosophiquement, je me méfie toujours des
solutions universelles ;-) Et le problème du .NET, c'est qu'il ne t'offre
pas d'autres paradigmes de programmation et restreint donc tes choix.
C++ est multi-paradigme et laisse plus de liberté (y compris celle de se
tirer dans le pied, c'est vrai).
A titre d'exemple, la programmation générique est en plein essort dans le
monde du C++ et on commence à peine à découvrir les possibilités qu'elle
offre - et non, les génériques de C# 2.0 ne permettent pas de faire de la
programmation générique, loin s'en faut!
Non, c'est faux.
Tout ce qui a été montré, c'est que <snip/>
- Avec un GC, l'allocation est plus rapide (on incrémente un compteur au
lieu de parcourir une liste chainée).
- Avec un GC, la désallocation est moins rapide (il faut parcourir
l'arborescence des références au lieu d'insérer un maillon dans une liste
chainée, plus la surcharge système de l'arrêt/synchronisation de tous les
threads du processus)
- Avec une gestion classique, <snip/>
mais le défaut c'est qu'on risque
d'avoir des "pauses" dans l'exécution du programme (pendant que le
GC tourne, tous les threads de l'appli sont bloqués), alors qu'avec
des destructions tout au long du fil du
programme, le temps passé dans ces destructions est "lissé" sur toute la
durée d'exécution.
C'est typiquement très visible en Java. Je dois
reconnaitre que c'est nettement moins perceptible en .NET : je suppose que
c'est lié essentiellement au mécanisme générationnel du GC .NET. Dans tous
les cas, ca rend bien sûr les GC inapliquables si on a des contraintes
temprs réel fortes - ce qui est rare j'en conviens.
Ceci dit, indépendamment de toutes ces considérations d'accro au
performances qui n'ont généralement pas beaucoup d'intérêt pratique, le GC
tel que proposé en .NET présente à mon avis 2 énormes défauts :
- l'idiome RAII (Ressource Acquisition Is Initialization) est
innapliquable<snip/>
- la séparation "les classes complexes sont allouées sur le tas et gérées
par le GC et les types primitifs et les objets simples (struct) sont
alloués sur la pile" est ridicule et n'a pas de sens du point de vue de la
conception objet pure. On peut très bien avoir besoin localement dans une
fonction d'un objet complexe (de par son arbre d'héritage, sa taille ou
autre), et il n'y a pas de raison de ne pas pouvoir l'allouer sur la pile.
.NET offre déjà une amélioration de ce point de vue par rapport à Java
grâce aux structs et au boxing/unboxing automatique, mais on n' a pas
encore la souplesse du C++ (au fait, toi qui te plaint des copies cachées
en C++, le > boxing/unboxing entraine des copies de l'objet!)
??? tu peux expliquer en quoi écrire un delete ressemble à "swapper vers
un> autre processus" (ce qui ne veut rien dire en soi...) ? Je te
qu'écrire un delete, ce n'est pas que libérer de la mémoire, c'est avant
tout appeler un destructeur (logiquement, c'est bien plus important).
Au passage, dans du code C++ *bien écrit*, il n'y a pas (ou très peu) de
delete.
On utilise RAII ! Je vois (et ponds) régulièrement du code C++ de
plus de 10000 ligne sans un seul delete dans le code utilisateir.
En ce qui concerne la taille "monstrueuse" (tu as des chiffres?) du code
de destruction des objets généré par le C++, c'est vrai que ce code prend
la place, mais :
- le GC aussi prend de la place :-)
- le code de destructions C++ fait partie du déroulement normal du
programme et bénéficie donc des effets de cache et de pipeline sur le
processeur. Par contre, quand le GC se déclenche, tu es bon à tous
les coups pour vider le <snip/>
> Mauvais plan sur la comète! Le marshalling entre les couches
managées et non managées est très inefficace! En plus, ...
<snip/> de nouveaux développements.
Deux petites remarques supplémentaires sur cet aspect :
- Actuellement, le compilateur C++ managé optimise mieux <snip/>
- Le compilateur JIT actuel n'optimise absolument pas pour le processeur
cible. Théoriquement, il est possible de faire un compilateur JIT qui
optimise le code pour la machine d'exécution <snip/>.
Mais qu'est ce qu'elle t'as fait la STL? Elle t'a traumatisée quand tu
étais petit ? ;-) Rien que pour la "type safety" qu'elle offre, je préfère
de loin la STL!
Je mettrais cependant un bémol : l'objet c'est très bien et même
indispensable, mais ca ne couvre pas tous les besoins et ce n'est pas la
solution universelle (philosophiquement, je me méfie toujours des
solutions universelles ;-) Et le problème du .NET, c'est qu'il ne t'offre
pas d'autres paradigmes de programmation et restreint donc tes choix.
C++ est multi-paradigme et laisse plus de liberté (y compris celle de se
tirer dans le pied, c'est vrai).
A titre d'exemple, la programmation générique est en plein essort dans le
monde du C++ et on commence à peine à découvrir les possibilités qu'elle
offre - et non, les génériques de C# 2.0 ne permettent pas de faire de la
programmation générique, loin s'en faut!
Non, c'est faux.
Tout ce qui a été montré, c'est que <snip/>
- Avec un GC, l'allocation est plus rapide (on incrémente un compteur au
lieu de parcourir une liste chainée).
- Avec un GC, la désallocation est moins rapide (il faut parcourir
l'arborescence des références au lieu d'insérer un maillon dans une liste
chainée, plus la surcharge système de l'arrêt/synchronisation de tous les
threads du processus)
- Avec une gestion classique, <snip/>
mais le défaut c'est qu'on risque
d'avoir des "pauses" dans l'exécution du programme (pendant que le
GC tourne, tous les threads de l'appli sont bloqués), alors qu'avec
des destructions tout au long du fil du
programme, le temps passé dans ces destructions est "lissé" sur toute la
durée d'exécution.
C'est typiquement très visible en Java. Je dois
reconnaitre que c'est nettement moins perceptible en .NET : je suppose que
c'est lié essentiellement au mécanisme générationnel du GC .NET. Dans tous
les cas, ca rend bien sûr les GC inapliquables si on a des contraintes
temprs réel fortes - ce qui est rare j'en conviens.
Ceci dit, indépendamment de toutes ces considérations d'accro au
performances qui n'ont généralement pas beaucoup d'intérêt pratique, le GC
tel que proposé en .NET présente à mon avis 2 énormes défauts :
- l'idiome RAII (Ressource Acquisition Is Initialization) est
innapliquable<snip/>
- la séparation "les classes complexes sont allouées sur le tas et gérées
par le GC et les types primitifs et les objets simples (struct) sont
alloués sur la pile" est ridicule et n'a pas de sens du point de vue de la
conception objet pure. On peut très bien avoir besoin localement dans une
fonction d'un objet complexe (de par son arbre d'héritage, sa taille ou
autre), et il n'y a pas de raison de ne pas pouvoir l'allouer sur la pile.
.NET offre déjà une amélioration de ce point de vue par rapport à Java
grâce aux structs et au boxing/unboxing automatique, mais on n' a pas
encore la souplesse du C++ (au fait, toi qui te plaint des copies cachées
en C++, le > boxing/unboxing entraine des copies de l'objet!)
??? tu peux expliquer en quoi écrire un delete ressemble à "swapper vers
un> autre processus" (ce qui ne veut rien dire en soi...) ? Je te
qu'écrire un delete, ce n'est pas que libérer de la mémoire, c'est avant
tout appeler un destructeur (logiquement, c'est bien plus important).
Au passage, dans du code C++ *bien écrit*, il n'y a pas (ou très peu) de
delete.
On utilise RAII ! Je vois (et ponds) régulièrement du code C++ de
plus de 10000 ligne sans un seul delete dans le code utilisateir.
En ce qui concerne la taille "monstrueuse" (tu as des chiffres?) du code
de destruction des objets généré par le C++, c'est vrai que ce code prend
la place, mais :
- le GC aussi prend de la place :-)
- le code de destructions C++ fait partie du déroulement normal du
programme et bénéficie donc des effets de cache et de pipeline sur le
processeur. Par contre, quand le GC se déclenche, tu es bon à tous
les coups pour vider le <snip/>
- Le compilateur JIT actuel n'optimise absolument pas pour le
processeur cible. Théoriquement, il est possible de faire un
compilateur JIT qui optimise le code pour la machine d'exécution
<snip/>.
c'est uniquement fondé sur le bon sens, mais autant
la transformation C#->PCode a de l'importance, autant PCode->Machine
n'en a pas trop, vu le faible niveau d'abstraction du PCode.
quand je vois comment un HP9000 optimise les branchements à la volée,
les pipelines pour le code, la vitesse à laquelle le materiel évolue
et tout et tout, ben je me dis que tout ça n'a pas grande importance.
Je mettrais cependant un bémol : l'objet c'est très bien et même
indispensable, mais ca ne couvre pas tous les besoins et ce n'est
pas la solution universelle (philosophiquement, je me méfie toujours
des solutions universelles ;-) Et le problème du .NET, c'est qu'il
ne t'offre pas d'autres paradigmes de programmation et restreint
donc tes choix.
C++ est multi-paradigme et laisse plus de liberté (y compris celle
de se tirer dans le pied, c'est vrai).
j'ai déja entendu un certain trollou dire ça :o)
A titre d'exemple, la programmation générique est en plein essort
dans le monde du C++ et on commence à peine à découvrir les
possibilités qu'elle offre - et non, les génériques de C# 2.0 ne
permettent pas de faire de la programmation générique, loin s'en
faut!
tu troll grave la.
List[E], c'est quoi si c'est pas de la genericité ?
bon, poussons le raisonnement. definissons une classe ArrayN<n> qui
est un tableau à n dimension. à ce jour je ne connais aucun langage
qui sait définir ArrayN<n> en fonction de ArrayN<n-1> et de
ArrayN<0>. pourtant c'est de la genericité ça. donc "les génériques
de C++ ne permettent pas de faire de la programmation générique, loin
s'en faut".
- Avec un GC, la désallocation est moins rapide (il faut parcourir
l'arborescence des références au lieu d'insérer un maillon dans une
liste chainée, plus la surcharge système de l'arrêt/synchronisation
de tous les threads du processus)
ça c'est une vision locale. mais globalement c'est rentable, même si
localement, ça peut couter plus cher.
- Avec une gestion classique, <snip/>
mais le défaut c'est qu'on risque
d'avoir des "pauses" dans l'exécution du programme (pendant que le
GC tourne, tous les threads de l'appli sont bloqués), alors qu'avec
des destructions tout au long du fil du
programme, le temps passé dans ces destructions est "lissé" sur
toute la durée d'exécution.
le concept de GC n'implique pas d'arreter tous les threads. cette
implantation le fait. c'est un choix. tant pis.
le risque de pause, je le mettait comme argument numero 1
de mes revendications trolleennes à la FAC. mais c'est du flan.
sur une execution, il y a du temps ou la machine ne branle rien.
pourquoi lisser le temps de destruction alors qu'on peut utiliser
le temps mort pour ça.
- l'idiome RAII (Ressource Acquisition Is Initialization) est
innapliquable<snip/>
prenons les streams. la fermeture du flux ne se fait pas de maniere
synchrone à la destruction puisque le destructeur est appellé quand
la machine a le temps. donc la fermeture est mise dans Close(), qu'on
appelle au moment souhaité. est-ce une bonne chose de vouloir
bourrer des fonctionalités dans le destructeur ? cela a t'il une
utilité réelle ? quelles bonnes propriétés/avantages cela est il censé
apporter ? a t'on vraiment besoin d'un tel mécanisme ? pourquoi ?
- la séparation "les classes complexes sont allouées sur le tas et
gérées par le GC et les types primitifs et les objets simples
(struct) sont alloués sur la pile" est ridicule et n'a pas de sens
du point de vue de la conception objet pure. On peut très bien avoir
besoin localement dans une fonction d'un objet complexe (de par son
arbre d'héritage, sa taille ou autre), et il n'y a pas de raison de
ne pas pouvoir l'allouer sur la pile. .NET offre déjà une
amélioration de ce point de vue par rapport à Java grâce aux structs
et au boxing/unboxing automatique, mais on n' a pas encore la
souplesse du C++ (au fait, toi qui te plaint des copies cachées en
C++, le > boxing/unboxing entraine des copies de l'objet!)
bof. moi je m'en fous que l'objet soit alloué sur la pile ou sur le
tas.
on donne la sémantique struct ou class à son objet selon le besoin
sémantique.
même concept en Eiffel (expanded). et l'exemple de christophe montre
qu'utiliser un struct ne sert pas à grand chose
(je pense que c'est
ça que tu appelles boxing unboxing).
je pense même qu'un jour,
le compilateur sera doté d'un mécanisme de decision qui choisira
localement entre struct ou class à la compilation.
??? tu peux expliquer en quoi écrire un delete ressemble à "swapper
vers un> autre processus" (ce qui ne veut rien dire en soi...) ? Je
te rappelles qu'écrire un delete, ce n'est pas que libérer de la
mémoire, c'est avant tout appeler un destructeur (logiquement, c'est
bien plus important).
tout est déja dit. quand je dis swapper vers un autre processus, je
parle du systeme multitache. et un destructeur, ça sert à liberer des
resources. confier des taches autres que ça au destructeur, bof...
Au passage, dans du code C++ *bien écrit*, il n'y a pas (ou très
peu) de delete.
c'est clair. une application qui fait de l'allocation à robinet
ouvert et passe un temps conséquent la dessus necessite qu'on
s'interroge.
En ce qui concerne la taille "monstrueuse" (tu as des chiffres?) du
code de destruction des objets généré par le C++, c'est vrai que ce
code prend de la place, mais :
il ne s'agit pas de cela du tout. je t'invite à relire.
pour faire une comparaison, écrire les delete, c'est comme écrire du
code
toutes les 3 lignes pour provoquer soit même le swap vers un autre
processus. ça fait perdre du temps à l'execution, ça prend une place
monstrueuse, ça donne au code une charge supplémentaire, et
conceptuellement, l'idée est naze.
il s'agit
d'opportunité du moment, et de complexité. je t'accorde
que ce n'est pas evident à saisir.
le type de mon objet
est decidé au milieu d'un calcul,
puis mon objet se balade,
et decider à un autre endroit du code si l'objet est encore
utilisé ou pas est extrement chiant.
- le code de destructions C++ fait partie du déroulement normal du
programme et bénéficie donc des effets de cache et de pipeline sur le
processeur. Par contre, quand le GC se déclenche, tu es bon à tous
les coups pour vider le <snip/>
le GC sera un jour aussi un "concept materiel".
je ne prend pas beaucoup de risques en affirmant cela.
Arnaud, je ne sais pas ce qu'il y a mais sur le coup la, et sur tes
posts precedents,
je trouve que tu as bouffé du troll...
- Le compilateur JIT actuel n'optimise absolument pas pour le
processeur cible. Théoriquement, il est possible de faire un
compilateur JIT qui optimise le code pour la machine d'exécution
<snip/>.
c'est uniquement fondé sur le bon sens, mais autant
la transformation C#->PCode a de l'importance, autant PCode->Machine
n'en a pas trop, vu le faible niveau d'abstraction du PCode.
quand je vois comment un HP9000 optimise les branchements à la volée,
les pipelines pour le code, la vitesse à laquelle le materiel évolue
et tout et tout, ben je me dis que tout ça n'a pas grande importance.
Je mettrais cependant un bémol : l'objet c'est très bien et même
indispensable, mais ca ne couvre pas tous les besoins et ce n'est
pas la solution universelle (philosophiquement, je me méfie toujours
des solutions universelles ;-) Et le problème du .NET, c'est qu'il
ne t'offre pas d'autres paradigmes de programmation et restreint
donc tes choix.
C++ est multi-paradigme et laisse plus de liberté (y compris celle
de se tirer dans le pied, c'est vrai).
j'ai déja entendu un certain trollou dire ça :o)
A titre d'exemple, la programmation générique est en plein essort
dans le monde du C++ et on commence à peine à découvrir les
possibilités qu'elle offre - et non, les génériques de C# 2.0 ne
permettent pas de faire de la programmation générique, loin s'en
faut!
tu troll grave la.
List[E], c'est quoi si c'est pas de la genericité ?
bon, poussons le raisonnement. definissons une classe ArrayN<n> qui
est un tableau à n dimension. à ce jour je ne connais aucun langage
qui sait définir ArrayN<n> en fonction de ArrayN<n-1> et de
ArrayN<0>. pourtant c'est de la genericité ça. donc "les génériques
de C++ ne permettent pas de faire de la programmation générique, loin
s'en faut".
- Avec un GC, la désallocation est moins rapide (il faut parcourir
l'arborescence des références au lieu d'insérer un maillon dans une
liste chainée, plus la surcharge système de l'arrêt/synchronisation
de tous les threads du processus)
ça c'est une vision locale. mais globalement c'est rentable, même si
localement, ça peut couter plus cher.
- Avec une gestion classique, <snip/>
mais le défaut c'est qu'on risque
d'avoir des "pauses" dans l'exécution du programme (pendant que le
GC tourne, tous les threads de l'appli sont bloqués), alors qu'avec
des destructions tout au long du fil du
programme, le temps passé dans ces destructions est "lissé" sur
toute la durée d'exécution.
le concept de GC n'implique pas d'arreter tous les threads. cette
implantation le fait. c'est un choix. tant pis.
le risque de pause, je le mettait comme argument numero 1
de mes revendications trolleennes à la FAC. mais c'est du flan.
sur une execution, il y a du temps ou la machine ne branle rien.
pourquoi lisser le temps de destruction alors qu'on peut utiliser
le temps mort pour ça.
- l'idiome RAII (Ressource Acquisition Is Initialization) est
innapliquable<snip/>
prenons les streams. la fermeture du flux ne se fait pas de maniere
synchrone à la destruction puisque le destructeur est appellé quand
la machine a le temps. donc la fermeture est mise dans Close(), qu'on
appelle au moment souhaité. est-ce une bonne chose de vouloir
bourrer des fonctionalités dans le destructeur ? cela a t'il une
utilité réelle ? quelles bonnes propriétés/avantages cela est il censé
apporter ? a t'on vraiment besoin d'un tel mécanisme ? pourquoi ?
- la séparation "les classes complexes sont allouées sur le tas et
gérées par le GC et les types primitifs et les objets simples
(struct) sont alloués sur la pile" est ridicule et n'a pas de sens
du point de vue de la conception objet pure. On peut très bien avoir
besoin localement dans une fonction d'un objet complexe (de par son
arbre d'héritage, sa taille ou autre), et il n'y a pas de raison de
ne pas pouvoir l'allouer sur la pile. .NET offre déjà une
amélioration de ce point de vue par rapport à Java grâce aux structs
et au boxing/unboxing automatique, mais on n' a pas encore la
souplesse du C++ (au fait, toi qui te plaint des copies cachées en
C++, le > boxing/unboxing entraine des copies de l'objet!)
bof. moi je m'en fous que l'objet soit alloué sur la pile ou sur le
tas.
on donne la sémantique struct ou class à son objet selon le besoin
sémantique.
même concept en Eiffel (expanded). et l'exemple de christophe montre
qu'utiliser un struct ne sert pas à grand chose
(je pense que c'est
ça que tu appelles boxing unboxing).
je pense même qu'un jour,
le compilateur sera doté d'un mécanisme de decision qui choisira
localement entre struct ou class à la compilation.
??? tu peux expliquer en quoi écrire un delete ressemble à "swapper
vers un> autre processus" (ce qui ne veut rien dire en soi...) ? Je
te rappelles qu'écrire un delete, ce n'est pas que libérer de la
mémoire, c'est avant tout appeler un destructeur (logiquement, c'est
bien plus important).
tout est déja dit. quand je dis swapper vers un autre processus, je
parle du systeme multitache. et un destructeur, ça sert à liberer des
resources. confier des taches autres que ça au destructeur, bof...
Au passage, dans du code C++ *bien écrit*, il n'y a pas (ou très
peu) de delete.
c'est clair. une application qui fait de l'allocation à robinet
ouvert et passe un temps conséquent la dessus necessite qu'on
s'interroge.
En ce qui concerne la taille "monstrueuse" (tu as des chiffres?) du
code de destruction des objets généré par le C++, c'est vrai que ce
code prend de la place, mais :
il ne s'agit pas de cela du tout. je t'invite à relire.
pour faire une comparaison, écrire les delete, c'est comme écrire du
code
toutes les 3 lignes pour provoquer soit même le swap vers un autre
processus. ça fait perdre du temps à l'execution, ça prend une place
monstrueuse, ça donne au code une charge supplémentaire, et
conceptuellement, l'idée est naze.
il s'agit
d'opportunité du moment, et de complexité. je t'accorde
que ce n'est pas evident à saisir.
le type de mon objet
est decidé au milieu d'un calcul,
puis mon objet se balade,
et decider à un autre endroit du code si l'objet est encore
utilisé ou pas est extrement chiant.
- le code de destructions C++ fait partie du déroulement normal du
programme et bénéficie donc des effets de cache et de pipeline sur le
processeur. Par contre, quand le GC se déclenche, tu es bon à tous
les coups pour vider le <snip/>
le GC sera un jour aussi un "concept materiel".
je ne prend pas beaucoup de risques en affirmant cela.
Arnaud, je ne sais pas ce qu'il y a mais sur le coup la, et sur tes
posts precedents,
je trouve que tu as bouffé du troll...
- Le compilateur JIT actuel n'optimise absolument pas pour le
processeur cible. Théoriquement, il est possible de faire un
compilateur JIT qui optimise le code pour la machine d'exécution
<snip/>.
c'est uniquement fondé sur le bon sens, mais autant
la transformation C#->PCode a de l'importance, autant PCode->Machine
n'en a pas trop, vu le faible niveau d'abstraction du PCode.
quand je vois comment un HP9000 optimise les branchements à la volée,
les pipelines pour le code, la vitesse à laquelle le materiel évolue
et tout et tout, ben je me dis que tout ça n'a pas grande importance.
Je mettrais cependant un bémol : l'objet c'est très bien et même
indispensable, mais ca ne couvre pas tous les besoins et ce n'est
pas la solution universelle (philosophiquement, je me méfie toujours
des solutions universelles ;-) Et le problème du .NET, c'est qu'il
ne t'offre pas d'autres paradigmes de programmation et restreint
donc tes choix.
C++ est multi-paradigme et laisse plus de liberté (y compris celle
de se tirer dans le pied, c'est vrai).
j'ai déja entendu un certain trollou dire ça :o)
A titre d'exemple, la programmation générique est en plein essort
dans le monde du C++ et on commence à peine à découvrir les
possibilités qu'elle offre - et non, les génériques de C# 2.0 ne
permettent pas de faire de la programmation générique, loin s'en
faut!
tu troll grave la.
List[E], c'est quoi si c'est pas de la genericité ?
bon, poussons le raisonnement. definissons une classe ArrayN<n> qui
est un tableau à n dimension. à ce jour je ne connais aucun langage
qui sait définir ArrayN<n> en fonction de ArrayN<n-1> et de
ArrayN<0>. pourtant c'est de la genericité ça. donc "les génériques
de C++ ne permettent pas de faire de la programmation générique, loin
s'en faut".
- Avec un GC, la désallocation est moins rapide (il faut parcourir
l'arborescence des références au lieu d'insérer un maillon dans une
liste chainée, plus la surcharge système de l'arrêt/synchronisation
de tous les threads du processus)
ça c'est une vision locale. mais globalement c'est rentable, même si
localement, ça peut couter plus cher.
- Avec une gestion classique, <snip/>
mais le défaut c'est qu'on risque
d'avoir des "pauses" dans l'exécution du programme (pendant que le
GC tourne, tous les threads de l'appli sont bloqués), alors qu'avec
des destructions tout au long du fil du
programme, le temps passé dans ces destructions est "lissé" sur
toute la durée d'exécution.
le concept de GC n'implique pas d'arreter tous les threads. cette
implantation le fait. c'est un choix. tant pis.
le risque de pause, je le mettait comme argument numero 1
de mes revendications trolleennes à la FAC. mais c'est du flan.
sur une execution, il y a du temps ou la machine ne branle rien.
pourquoi lisser le temps de destruction alors qu'on peut utiliser
le temps mort pour ça.
- l'idiome RAII (Ressource Acquisition Is Initialization) est
innapliquable<snip/>
prenons les streams. la fermeture du flux ne se fait pas de maniere
synchrone à la destruction puisque le destructeur est appellé quand
la machine a le temps. donc la fermeture est mise dans Close(), qu'on
appelle au moment souhaité. est-ce une bonne chose de vouloir
bourrer des fonctionalités dans le destructeur ? cela a t'il une
utilité réelle ? quelles bonnes propriétés/avantages cela est il censé
apporter ? a t'on vraiment besoin d'un tel mécanisme ? pourquoi ?
- la séparation "les classes complexes sont allouées sur le tas et
gérées par le GC et les types primitifs et les objets simples
(struct) sont alloués sur la pile" est ridicule et n'a pas de sens
du point de vue de la conception objet pure. On peut très bien avoir
besoin localement dans une fonction d'un objet complexe (de par son
arbre d'héritage, sa taille ou autre), et il n'y a pas de raison de
ne pas pouvoir l'allouer sur la pile. .NET offre déjà une
amélioration de ce point de vue par rapport à Java grâce aux structs
et au boxing/unboxing automatique, mais on n' a pas encore la
souplesse du C++ (au fait, toi qui te plaint des copies cachées en
C++, le > boxing/unboxing entraine des copies de l'objet!)
bof. moi je m'en fous que l'objet soit alloué sur la pile ou sur le
tas.
on donne la sémantique struct ou class à son objet selon le besoin
sémantique.
même concept en Eiffel (expanded). et l'exemple de christophe montre
qu'utiliser un struct ne sert pas à grand chose
(je pense que c'est
ça que tu appelles boxing unboxing).
je pense même qu'un jour,
le compilateur sera doté d'un mécanisme de decision qui choisira
localement entre struct ou class à la compilation.
??? tu peux expliquer en quoi écrire un delete ressemble à "swapper
vers un> autre processus" (ce qui ne veut rien dire en soi...) ? Je
te rappelles qu'écrire un delete, ce n'est pas que libérer de la
mémoire, c'est avant tout appeler un destructeur (logiquement, c'est
bien plus important).
tout est déja dit. quand je dis swapper vers un autre processus, je
parle du systeme multitache. et un destructeur, ça sert à liberer des
resources. confier des taches autres que ça au destructeur, bof...
Au passage, dans du code C++ *bien écrit*, il n'y a pas (ou très
peu) de delete.
c'est clair. une application qui fait de l'allocation à robinet
ouvert et passe un temps conséquent la dessus necessite qu'on
s'interroge.
En ce qui concerne la taille "monstrueuse" (tu as des chiffres?) du
code de destruction des objets généré par le C++, c'est vrai que ce
code prend de la place, mais :
il ne s'agit pas de cela du tout. je t'invite à relire.
pour faire une comparaison, écrire les delete, c'est comme écrire du
code
toutes les 3 lignes pour provoquer soit même le swap vers un autre
processus. ça fait perdre du temps à l'execution, ça prend une place
monstrueuse, ça donne au code une charge supplémentaire, et
conceptuellement, l'idée est naze.
il s'agit
d'opportunité du moment, et de complexité. je t'accorde
que ce n'est pas evident à saisir.
le type de mon objet
est decidé au milieu d'un calcul,
puis mon objet se balade,
et decider à un autre endroit du code si l'objet est encore
utilisé ou pas est extrement chiant.
- le code de destructions C++ fait partie du déroulement normal du
programme et bénéficie donc des effets de cache et de pipeline sur le
processeur. Par contre, quand le GC se déclenche, tu es bon à tous
les coups pour vider le <snip/>
le GC sera un jour aussi un "concept materiel".
je ne prend pas beaucoup de risques en affirmant cela.
Arnaud, je ne sais pas ce qu'il y a mais sur le coup la, et sur tes
posts precedents,
je trouve que tu as bouffé du troll...
> Je disais juste ça par rapport au fait que l'argument "le compilateur JIT
optimisateur de la mort qui tue pour ton processeur particulier à toi" est
souvent ressorti par les zélotes de .NET alors que c'est un argument
fallacieux.
j'ai déja entendu un certain trollou dire ça :o)
L'histoire de la balle dans le pied, c'est une citation de Stroustrup.
Maintenant, si tu veux considérer que Stroustrup est un troll, je te
laisse la responsabilité de tes opinions! ;-)
List[E], c'est quoi si c'est pas de la genericité ?
La *programmation* générique, comme toute programmation, doit remplir au
minimum <snip/>
Comme c'est un sujet HS et trop long pour être abordé en détail ici, je
t'invite à te pencher sur le bouquin "Modern C++ Design" et sur la
bibliothèque associée, Loki, si tu veux plus de détails sur ce sujet.
C'est le seul bouqin en informatique qui m'as véritablement mis le c*
part terre récemment.
Dans le même genre en plus simple, les templates C++ permettent de définir
une fonction factorielle exactement sur le même principe. C'est une valeur
entièrement calculée à la compilation et dont le temps d'exécution est
donc constant :
ça c'est une vision locale. mais globalement c'est rentable, même si
localement, ça peut couter plus cher.
Tu pourrais démontrer cette assertion par un calcul de complexité, même
qualitatif?
le concept de GC n'implique pas d'arreter tous les threads. cette
implantation le fait. c'est un choix. tant pis.
Tu as déjà vu une implémentation de GC qui ferait autrement?
J'ai beau me torturer l'esprit, je ne vois pas comment c'est
conceptuelement faisable vu que le GC va déplacer en mémoire
des objets susceptibles d'êtres manipulés en même temps par les
threads de l'application.
Je repose la question : as-tu déjà vu une implémentation de GC qui fasse
comme çà? Toutes celles que je connais se déclenchent quand elles
détectent que le système est en passe de manquer de mémoire, ou bien
à intervalle régulier.
- l'idiome RAII (Ressource Acquisition Is Initialization) est
innapliquable<snip/>
- Si la ressource est critique et doit être libérée le plus rapidement
possible (un périphérique matériel par exemple), alors oui c'est utile.
- Plus important, pour écrire du code "exception safe", la seule façon de
faire en C# <snip/>
Ben justement, si je veux définir un objet à comportement polymorphique
(ou contenant un objet polymorphiqe pour être plus réaliste) mais à durée
vie automatique, je fais comment?
Quel exemple de Christophe? Je n'ai pas la référence dont tu parles.
> (je pense que c'est
> ça que tu appelles boxing unboxing).
Pour faire simple, le boxing/unboxing, c'est la capacité de C# de
transformer une "value type" en object :
int i 3;
object o =i; //ici, une copie de i est réalisée sur le tas.
> je pense même qu'un jour,
> le compilateur sera doté d'un mécanisme de decision qui choisira
> localement entre struct ou class à la compilation.
Fichtre..., on parle bien du C# là? Parce qu'alors il faudra revoir les
définitions de class et struct dans ce langage vu que ces deux concepts ne
permettent pas de faire la même chose! Entre autres différences :
- une struct ne peut que hériter d'object et implémenter des interfaces
Au passage, dans du code C++ *bien écrit*, il n'y a pas (ou très
peu) de delete.
c'est clair. une application qui fait de l'allocation à robinet
ouvert et passe un temps conséquent la dessus necessite qu'on
s'interroge.
Non, tu ne m'as pas compris (au passage, un programme .NET va
avoir tendance à faire beaucoup plus d'allocations mémoire qu'un
programme C++). : Je parle du fait qu'en C++ on s'arrange pour
que le langage fasse lui même le ménage (via les destructeurs) pour
les ressoures qu'on alloue et ce de manière synchrone.
il ne s'agit pas de cela du tout. je t'invite à relire.
Je relis donc :pour faire une comparaison, écrire les delete, c'est comme écrire du
code toutes les 3 lignes pour provoquer soit même le swap vers un
autre processus. ça fait perdre du temps à l'execution, ça prend une
place monstrueuse, ça donne au code une charge supplémentaire, et
conceptuellement, l'idée est naze.
Pourrais-tu m'expliquer ton parallélisme, parce que j'avoue que je ne vois
toujours pas le rapport entre le swap d'un thread à l'autre (qui sert à
faire plusieurs tâches en "pseudo-parallèle" sur un processeur) et la
politique de libération des ressources d'un programme donné.
il s'agit
d'opportunité du moment, et de complexité. je t'accorde
que ce n'est pas evident à saisir.
Non, c'est le moins qu'on puiss dire, essaie de clarifier!
bon pourquoi pa... Moi ce qui m'intéresse (et surtout mon patron!), c'est
*aujourd'hui* de savoir l'impact du choix de C# pour faire telle ou telle
chose, pas dans un futur hypothétique.
Arnaud, je ne sais pas ce qu'il y a mais sur le coup la, et sur tes
posts precedents, je trouve que tu as bouffé du troll...
Fichtre, d'autres ont eu la même impression là??? Va peut être falloir que
je me soigne alors! ;-)
Sérieusement, ca ne serait pas toi qui ferait dans la paranoia trollesque
et manquerait un peu d'objectivité dans tes jugements?
.NET a d'immenses
qualités (la richesse et la qualité de la BC et du framework, la
simplicité de codage, la gestion des assembly et la fin du DLL-hell, ...),
mais tout MVP que je suis, ca ne m'empêche pas de rester critique
malgré tout!
> Je disais juste ça par rapport au fait que l'argument "le compilateur JIT
optimisateur de la mort qui tue pour ton processeur particulier à toi" est
souvent ressorti par les zélotes de .NET alors que c'est un argument
fallacieux.
j'ai déja entendu un certain trollou dire ça :o)
L'histoire de la balle dans le pied, c'est une citation de Stroustrup.
Maintenant, si tu veux considérer que Stroustrup est un troll, je te
laisse la responsabilité de tes opinions! ;-)
List[E], c'est quoi si c'est pas de la genericité ?
La *programmation* générique, comme toute programmation, doit remplir au
minimum <snip/>
Comme c'est un sujet HS et trop long pour être abordé en détail ici, je
t'invite à te pencher sur le bouquin "Modern C++ Design" et sur la
bibliothèque associée, Loki, si tu veux plus de détails sur ce sujet.
C'est le seul bouqin en informatique qui m'as véritablement mis le c*
part terre récemment.
Dans le même genre en plus simple, les templates C++ permettent de définir
une fonction factorielle exactement sur le même principe. C'est une valeur
entièrement calculée à la compilation et dont le temps d'exécution est
donc constant :
ça c'est une vision locale. mais globalement c'est rentable, même si
localement, ça peut couter plus cher.
Tu pourrais démontrer cette assertion par un calcul de complexité, même
qualitatif?
le concept de GC n'implique pas d'arreter tous les threads. cette
implantation le fait. c'est un choix. tant pis.
Tu as déjà vu une implémentation de GC qui ferait autrement?
J'ai beau me torturer l'esprit, je ne vois pas comment c'est
conceptuelement faisable vu que le GC va déplacer en mémoire
des objets susceptibles d'êtres manipulés en même temps par les
threads de l'application.
Je repose la question : as-tu déjà vu une implémentation de GC qui fasse
comme çà? Toutes celles que je connais se déclenchent quand elles
détectent que le système est en passe de manquer de mémoire, ou bien
à intervalle régulier.
- l'idiome RAII (Ressource Acquisition Is Initialization) est
innapliquable<snip/>
- Si la ressource est critique et doit être libérée le plus rapidement
possible (un périphérique matériel par exemple), alors oui c'est utile.
- Plus important, pour écrire du code "exception safe", la seule façon de
faire en C# <snip/>
Ben justement, si je veux définir un objet à comportement polymorphique
(ou contenant un objet polymorphiqe pour être plus réaliste) mais à durée
vie automatique, je fais comment?
Quel exemple de Christophe? Je n'ai pas la référence dont tu parles.
> (je pense que c'est
> ça que tu appelles boxing unboxing).
Pour faire simple, le boxing/unboxing, c'est la capacité de C# de
transformer une "value type" en object :
int i 3;
object o =i; //ici, une copie de i est réalisée sur le tas.
> je pense même qu'un jour,
> le compilateur sera doté d'un mécanisme de decision qui choisira
> localement entre struct ou class à la compilation.
Fichtre..., on parle bien du C# là? Parce qu'alors il faudra revoir les
définitions de class et struct dans ce langage vu que ces deux concepts ne
permettent pas de faire la même chose! Entre autres différences :
- une struct ne peut que hériter d'object et implémenter des interfaces
Au passage, dans du code C++ *bien écrit*, il n'y a pas (ou très
peu) de delete.
c'est clair. une application qui fait de l'allocation à robinet
ouvert et passe un temps conséquent la dessus necessite qu'on
s'interroge.
Non, tu ne m'as pas compris (au passage, un programme .NET va
avoir tendance à faire beaucoup plus d'allocations mémoire qu'un
programme C++). : Je parle du fait qu'en C++ on s'arrange pour
que le langage fasse lui même le ménage (via les destructeurs) pour
les ressoures qu'on alloue et ce de manière synchrone.
il ne s'agit pas de cela du tout. je t'invite à relire.
Je relis donc :
pour faire une comparaison, écrire les delete, c'est comme écrire du
code toutes les 3 lignes pour provoquer soit même le swap vers un
autre processus. ça fait perdre du temps à l'execution, ça prend une
place monstrueuse, ça donne au code une charge supplémentaire, et
conceptuellement, l'idée est naze.
Pourrais-tu m'expliquer ton parallélisme, parce que j'avoue que je ne vois
toujours pas le rapport entre le swap d'un thread à l'autre (qui sert à
faire plusieurs tâches en "pseudo-parallèle" sur un processeur) et la
politique de libération des ressources d'un programme donné.
il s'agit
d'opportunité du moment, et de complexité. je t'accorde
que ce n'est pas evident à saisir.
Non, c'est le moins qu'on puiss dire, essaie de clarifier!
bon pourquoi pa... Moi ce qui m'intéresse (et surtout mon patron!), c'est
*aujourd'hui* de savoir l'impact du choix de C# pour faire telle ou telle
chose, pas dans un futur hypothétique.
Arnaud, je ne sais pas ce qu'il y a mais sur le coup la, et sur tes
posts precedents, je trouve que tu as bouffé du troll...
Fichtre, d'autres ont eu la même impression là??? Va peut être falloir que
je me soigne alors! ;-)
Sérieusement, ca ne serait pas toi qui ferait dans la paranoia trollesque
et manquerait un peu d'objectivité dans tes jugements?
.NET a d'immenses
qualités (la richesse et la qualité de la BC et du framework, la
simplicité de codage, la gestion des assembly et la fin du DLL-hell, ...),
mais tout MVP que je suis, ca ne m'empêche pas de rester critique
malgré tout!
> Je disais juste ça par rapport au fait que l'argument "le compilateur JIT
optimisateur de la mort qui tue pour ton processeur particulier à toi" est
souvent ressorti par les zélotes de .NET alors que c'est un argument
fallacieux.
j'ai déja entendu un certain trollou dire ça :o)
L'histoire de la balle dans le pied, c'est une citation de Stroustrup.
Maintenant, si tu veux considérer que Stroustrup est un troll, je te
laisse la responsabilité de tes opinions! ;-)
List[E], c'est quoi si c'est pas de la genericité ?
La *programmation* générique, comme toute programmation, doit remplir au
minimum <snip/>
Comme c'est un sujet HS et trop long pour être abordé en détail ici, je
t'invite à te pencher sur le bouquin "Modern C++ Design" et sur la
bibliothèque associée, Loki, si tu veux plus de détails sur ce sujet.
C'est le seul bouqin en informatique qui m'as véritablement mis le c*
part terre récemment.
Dans le même genre en plus simple, les templates C++ permettent de définir
une fonction factorielle exactement sur le même principe. C'est une valeur
entièrement calculée à la compilation et dont le temps d'exécution est
donc constant :
ça c'est une vision locale. mais globalement c'est rentable, même si
localement, ça peut couter plus cher.
Tu pourrais démontrer cette assertion par un calcul de complexité, même
qualitatif?
le concept de GC n'implique pas d'arreter tous les threads. cette
implantation le fait. c'est un choix. tant pis.
Tu as déjà vu une implémentation de GC qui ferait autrement?
J'ai beau me torturer l'esprit, je ne vois pas comment c'est
conceptuelement faisable vu que le GC va déplacer en mémoire
des objets susceptibles d'êtres manipulés en même temps par les
threads de l'application.
Je repose la question : as-tu déjà vu une implémentation de GC qui fasse
comme çà? Toutes celles que je connais se déclenchent quand elles
détectent que le système est en passe de manquer de mémoire, ou bien
à intervalle régulier.
- l'idiome RAII (Ressource Acquisition Is Initialization) est
innapliquable<snip/>
- Si la ressource est critique et doit être libérée le plus rapidement
possible (un périphérique matériel par exemple), alors oui c'est utile.
- Plus important, pour écrire du code "exception safe", la seule façon de
faire en C# <snip/>
Ben justement, si je veux définir un objet à comportement polymorphique
(ou contenant un objet polymorphiqe pour être plus réaliste) mais à durée
vie automatique, je fais comment?
Quel exemple de Christophe? Je n'ai pas la référence dont tu parles.
> (je pense que c'est
> ça que tu appelles boxing unboxing).
Pour faire simple, le boxing/unboxing, c'est la capacité de C# de
transformer une "value type" en object :
int i 3;
object o =i; //ici, une copie de i est réalisée sur le tas.
> je pense même qu'un jour,
> le compilateur sera doté d'un mécanisme de decision qui choisira
> localement entre struct ou class à la compilation.
Fichtre..., on parle bien du C# là? Parce qu'alors il faudra revoir les
définitions de class et struct dans ce langage vu que ces deux concepts ne
permettent pas de faire la même chose! Entre autres différences :
- une struct ne peut que hériter d'object et implémenter des interfaces
Au passage, dans du code C++ *bien écrit*, il n'y a pas (ou très
peu) de delete.
c'est clair. une application qui fait de l'allocation à robinet
ouvert et passe un temps conséquent la dessus necessite qu'on
s'interroge.
Non, tu ne m'as pas compris (au passage, un programme .NET va
avoir tendance à faire beaucoup plus d'allocations mémoire qu'un
programme C++). : Je parle du fait qu'en C++ on s'arrange pour
que le langage fasse lui même le ménage (via les destructeurs) pour
les ressoures qu'on alloue et ce de manière synchrone.
il ne s'agit pas de cela du tout. je t'invite à relire.
Je relis donc :pour faire une comparaison, écrire les delete, c'est comme écrire du
code toutes les 3 lignes pour provoquer soit même le swap vers un
autre processus. ça fait perdre du temps à l'execution, ça prend une
place monstrueuse, ça donne au code une charge supplémentaire, et
conceptuellement, l'idée est naze.
Pourrais-tu m'expliquer ton parallélisme, parce que j'avoue que je ne vois
toujours pas le rapport entre le swap d'un thread à l'autre (qui sert à
faire plusieurs tâches en "pseudo-parallèle" sur un processeur) et la
politique de libération des ressources d'un programme donné.
il s'agit
d'opportunité du moment, et de complexité. je t'accorde
que ce n'est pas evident à saisir.
Non, c'est le moins qu'on puiss dire, essaie de clarifier!
bon pourquoi pa... Moi ce qui m'intéresse (et surtout mon patron!), c'est
*aujourd'hui* de savoir l'impact du choix de C# pour faire telle ou telle
chose, pas dans un futur hypothétique.
Arnaud, je ne sais pas ce qu'il y a mais sur le coup la, et sur tes
posts precedents, je trouve que tu as bouffé du troll...
Fichtre, d'autres ont eu la même impression là??? Va peut être falloir que
je me soigne alors! ;-)
Sérieusement, ca ne serait pas toi qui ferait dans la paranoia trollesque
et manquerait un peu d'objectivité dans tes jugements?
.NET a d'immenses
qualités (la richesse et la qualité de la BC et du framework, la
simplicité de codage, la gestion des assembly et la fin du DLL-hell, ...),
mais tout MVP que je suis, ca ne m'empêche pas de rester critique
malgré tout!