Il est incohérent de critiquer un microbenchmark « non réaliste » et d'expliquer ensuite que le C(++) permet des tas de micro-optimisations coûteuses en développement et en maintenance, comme si c'était « réaliste » de faire ce genre de micro-optimisations sur des applications de la vraie vie.
Ta critique ne tient (et encore que vaguement) que dans le cadre de ce micro-bench. Dans le cadre d'une vrai application ce genre d'«optimisation» n'est pas couteux en dévelopement et en maintenance.
Tout d'abord, tu trouvera de nombreuse classe sur le net, déjà testées intensivement, qui implémentent ce genre de pool. Donc le cout de dévellopement à ce niveau est quasiment nul. Tu commence par créer un pool en lui donnant éventuellement une indication du nombre d'élément que tu pense créer, et ensuite tu lui demande et et éventuellement redonne les objets de la même manière que les allouerais/libererais de manière classique. Avec l'avantage que tu as un netoyage global à la fin en libérant le pool.
Donc tu peut même gagner du temps dans certains cas, en éliminant la nécéssitée de libéré les objets au fur et à mesure.
Ensuite, un objet qui doit être créer à suffisament d'exemplaire pour qu'utiliser un pool soit vraiment intéressant c'est pas forcément tous les jours que tu en rencontre. Donc de base c'est le genre de chose auquel on a tendance à penser au moment ou l'on prévoit le design de l'application, pas en dernière minute.
De manière plus générale, l'utilisation d'un pool n'est pas, comme tu le dis, une «micro-optimisation» mais un point de design et dans des programme réaliste, les cas ou tu dois le mettre en oeuvre ne sont pas si fréquents, sont bien prévu, et au final ne complexifie pas le code mais on tendance à le simplifier beaucoup quand c'est bien fait.
Avec quelque classes génériques, tu obtient les avantage de la gestion manuelle et des GC. Dans les zones qui n'ont pas être rapide, tu peux utiliser la libération automatique, les auto pointer... Et dans les zones critiques tu utilises une gestion manuelle et des pool automatique quand c'est nécéssaire.
Le développeur utilisant un langage plus haut niveau aura écrit un logiciel à la couverture fonctionnelle trois fois plus grande, et qui apporte plus aux utilisateurs.
C'est un joli mythe mais dans la réalitée c'est loin d'être toujours le cas. Il y a énormément de chose qui jouent dans ta capacité à produire du code et le niveau d'abstraction ou de fonctionalité du langage n'est pas la plus importante.
De manière générale il faut être capable de choisir le langage adapté à la tache et à l'environement. Je n'utilserais pas du C pour faire un programme qui fait des manipulations complexe de chaine de caractère sur un petit volume de donnée une fois par mois, tout comme je n'utilserais du bash pour faire un calcul scientifque complexe qui tournera sur un gros serveur de calcul.
Pour revenir au sujet de base : le garbage collector, J'ai eu un soucis il y a de cela quelque temps :
Un petit programme pas extrèmement compliqué qui lisait un fichier ligne par ligne. Il découpait la lignes, faisait quelques traitement et reassemblait une nouvelle ligne pour la sortie.
J'ai fait une première version de ce programme en Lua, ce fut rapide à programmer, mais le programme devenait vite lent à mourir des que le fichier grossisait un peu.Sur le moment je n'avais ps le temps de chercher plus loin, j'ai donc recoder le truc en C en au final c'est les disque qui ne suivait plus le rythme. (ce qui dans mon cas n'était pas génant puisque la sortie du programme était traiter par un autre programme qui prenait le reste du temps CPU)
Quelques temps plus tard, je me repenche sur le problème pour en déterminer la cause. J'aime beaucoup utiliser des langages de scripts pour prototyper des programmes ou pour des petits dévellopement qui n'on pas à être particulièrement rapide. Lua est un langage que j'apprécie beaucoup et donc j'avais envie de savoir d'ou venait vraiment le problème. Après investigation, le problème venait à la fois du GC et du fait que les chaine sont imutables dans lua : chaque ligne représentait un objet, mais aussi chaque morceau de la ligne découpée, chaque étape de transformation de ces morceaux ainsi que la ligne finale. Ce qui fait que pour chaque ligne traité, de nombreux petits objets était créés et le GC se déclenchait sans arret et libérait tous ceux des lignes précédentes. Bref pas mal de boulot inutile.
La version en C utilisait juste deux buffer alloués statiquement.
Cet exemple est, en partie, lié à la gestion des chaines imutable de lua, mais surtout met en avant le problème de ces langages de haut niveaux : Il y a beaucoup de choses qui sont cachées et que l'on ne peut pas forcément prédir et dont on ne connait pas forcément les conséquences. Et l'utilisation d'un GC peut cacher certains problèmes qui serait explicite sans eux.
C'est quand tous les outils, il font utiliser le bon au bon moment, c'est tout.
Donc, pour en revenir au bench, je maintient que celon moi il est stupide et ne prouve qu'une chose, quand on demande à C++ de faire quelque chose de stupide et qu'on lui demande mal, il est plus lent que OOC.
Ce qui ne donne aucune information sur les perfs réelles de OOC.
[^] # Re: Rapidité du C ... et ramasse-miettes ?
Posté par beagf . En réponse à la dépêche Le language de programmation ooc sorti en version 0.2. Évalué à 4.
Ta critique ne tient (et encore que vaguement) que dans le cadre de ce micro-bench. Dans le cadre d'une vrai application ce genre d'«optimisation» n'est pas couteux en dévelopement et en maintenance.
Tout d'abord, tu trouvera de nombreuse classe sur le net, déjà testées intensivement, qui implémentent ce genre de pool. Donc le cout de dévellopement à ce niveau est quasiment nul. Tu commence par créer un pool en lui donnant éventuellement une indication du nombre d'élément que tu pense créer, et ensuite tu lui demande et et éventuellement redonne les objets de la même manière que les allouerais/libererais de manière classique. Avec l'avantage que tu as un netoyage global à la fin en libérant le pool.
Donc tu peut même gagner du temps dans certains cas, en éliminant la nécéssitée de libéré les objets au fur et à mesure.
Ensuite, un objet qui doit être créer à suffisament d'exemplaire pour qu'utiliser un pool soit vraiment intéressant c'est pas forcément tous les jours que tu en rencontre. Donc de base c'est le genre de chose auquel on a tendance à penser au moment ou l'on prévoit le design de l'application, pas en dernière minute.
De manière plus générale, l'utilisation d'un pool n'est pas, comme tu le dis, une «micro-optimisation» mais un point de design et dans des programme réaliste, les cas ou tu dois le mettre en oeuvre ne sont pas si fréquents, sont bien prévu, et au final ne complexifie pas le code mais on tendance à le simplifier beaucoup quand c'est bien fait.
Avec quelque classes génériques, tu obtient les avantage de la gestion manuelle et des GC. Dans les zones qui n'ont pas être rapide, tu peux utiliser la libération automatique, les auto pointer... Et dans les zones critiques tu utilises une gestion manuelle et des pool automatique quand c'est nécéssaire.
Le développeur utilisant un langage plus haut niveau aura écrit un logiciel à la couverture fonctionnelle trois fois plus grande, et qui apporte plus aux utilisateurs.
C'est un joli mythe mais dans la réalitée c'est loin d'être toujours le cas. Il y a énormément de chose qui jouent dans ta capacité à produire du code et le niveau d'abstraction ou de fonctionalité du langage n'est pas la plus importante.
De manière générale il faut être capable de choisir le langage adapté à la tache et à l'environement. Je n'utilserais pas du C pour faire un programme qui fait des manipulations complexe de chaine de caractère sur un petit volume de donnée une fois par mois, tout comme je n'utilserais du bash pour faire un calcul scientifque complexe qui tournera sur un gros serveur de calcul.
Pour revenir au sujet de base : le garbage collector, J'ai eu un soucis il y a de cela quelque temps :
Un petit programme pas extrèmement compliqué qui lisait un fichier ligne par ligne. Il découpait la lignes, faisait quelques traitement et reassemblait une nouvelle ligne pour la sortie.
J'ai fait une première version de ce programme en Lua, ce fut rapide à programmer, mais le programme devenait vite lent à mourir des que le fichier grossisait un peu.Sur le moment je n'avais ps le temps de chercher plus loin, j'ai donc recoder le truc en C en au final c'est les disque qui ne suivait plus le rythme. (ce qui dans mon cas n'était pas génant puisque la sortie du programme était traiter par un autre programme qui prenait le reste du temps CPU)
Quelques temps plus tard, je me repenche sur le problème pour en déterminer la cause. J'aime beaucoup utiliser des langages de scripts pour prototyper des programmes ou pour des petits dévellopement qui n'on pas à être particulièrement rapide. Lua est un langage que j'apprécie beaucoup et donc j'avais envie de savoir d'ou venait vraiment le problème. Après investigation, le problème venait à la fois du GC et du fait que les chaine sont imutables dans lua : chaque ligne représentait un objet, mais aussi chaque morceau de la ligne découpée, chaque étape de transformation de ces morceaux ainsi que la ligne finale. Ce qui fait que pour chaque ligne traité, de nombreux petits objets était créés et le GC se déclenchait sans arret et libérait tous ceux des lignes précédentes. Bref pas mal de boulot inutile.
La version en C utilisait juste deux buffer alloués statiquement.
Cet exemple est, en partie, lié à la gestion des chaines imutable de lua, mais surtout met en avant le problème de ces langages de haut niveaux : Il y a beaucoup de choses qui sont cachées et que l'on ne peut pas forcément prédir et dont on ne connait pas forcément les conséquences. Et l'utilisation d'un GC peut cacher certains problèmes qui serait explicite sans eux.
C'est quand tous les outils, il font utiliser le bon au bon moment, c'est tout.
Donc, pour en revenir au bench, je maintient que celon moi il est stupide et ne prouve qu'une chose, quand on demande à C++ de faire quelque chose de stupide et qu'on lui demande mal, il est plus lent que OOC.
Ce qui ne donne aucune information sur les perfs réelles de OOC.