Bonjour GrégoryEnvoyé par Grégory Picavet
Ce n'est pas cool de pinailler. Le fait qu'une problème soit reporté comme
une erreur ou un avertissement depend simplement des options de compilation,
c-a-d des souhaits de l'utilisateur. On peut transformer le warning
gcc en erreur baveuse (option -pedantic-errors la bien nommée),
ou même n'avoir aucun rapport d'erreur si on le désire.
Ca n'a pas grand chose à voir avec le langage.
Ce qui est important c'est que la sémantique du langage fasse que le compilateur
puisse détecter un problème.
javac dit "problème potentiel" (il a raison, ce n'est pas
forcément un problème)
et gcc dit "attention, assignation d'un double à un int",
après c'est au programmeur de prendre ses responsabilités.
Pour la suite de ton intervention, je suis perplexe car
int i = (int) 0.5f ; est exactement ce qu'on *pourrait* écrire
aussi en C++ pour être clean avec le compilo.
Pour cet exemple précis, je parlerais d'ailleurs plutôt de conversion, car
un "int" n'est pas un objet en Java(1)(2) (pas plus qu'en C++ d'ailleurs).
On ne peut donc pas parler de relation "est-un" (qui est modélisé par
l'héritage en programmation objet).
On a plutôt une relation "peut-etre-converti-en" dans les deux langages
avec des garde-fous pour éviter de convertir n'importe quoi
en n'importe quoi.
C++ propose d'ailleurs la conversion
static_cast<Type_cible>(expression) servant (je cite) aux
"conversions bien définies, mais non-sûres".
Comme nous sommes en plein dans ce cas, ton exemple s'écrirait proprement
int i = static_cast<int>( 0.5f ) ;
en C++, ce qui est plus précis que la version Java.
On dispose aussi de reinterpret_cast, const_cast et dynamic_cast
pour préciser explicitement ses intentions lors d'un conversion.
Donc, cher contradicteur, je me permet de nuancer vos affirmations.
(1) Ceci montre d'ailleurs que la réclame
"Java est 100% objet" n'engage que ceux qui la croient.
(2) J'irai plus loin : un String n'est pas un objet non plus, c'est un
être hybride qui a certaines propriétés des objets et des types natifs.
------
Oui, etc.. Sauf que :arithmétique des pointeurs ca veut bien dire : si p1, p2 sont des pointeurs alors p1+p2 aussi, p1-p2, p1+1, etc... et donc permettent d'accéder à la mémoire un peu n'importe comment. En java, évidemment, ca n'a aucun sens. l'accès à la mémoire se fait par conteneur (avec get/set). D'ou un accroissement de la sécurité. De plus on peut convertir un tableau de type primitif en son équivalent DirectBuffer (et inversement) dans l'ordre natif des octets de la machine, de manière transparente.
1) p1+p2 n'a pas de sens physique (somme de 2 adresses) et ne compile
même pas.
2) p1-p2 a un sens mais n'est pas un pointeur, c'est un entier
(nombre d'éléments entre les deux adresses)
3) seul, p1+1 est bien un pointeur.
Dans ces conditions on comprend pourquoi la mémoire est accédée n'importe
comment.
Bonne dans l'absolu ne signifie pas grand chose (bonne pour quoi ?)est-ce donc que tu reconnais que la philosophie de java est bonne est que le c++ n'a pas de brillant avenir?Je prédis un "brillant" avenir à ce paquetage. Il est en contradiction
avec la philosophie de Java..Bon évidement c'est pas aussi simple. De plus, les buffer à accès direct ne sont qu'un cas particulier de ce package. Les entrès-sorties étaient le point faible de java. Le package nio permet de réaliser enfin des applications très performantes, capable de monter en charge. Le package io permet de gérer simplement la mémoire avec des performances qui sont bien connues (à cause du blocage avec les threads entre autres)...Le package nio, un peu plus complexe permet de gérer précisement les buffers sans blocage. Les domaines de prédilection de ce package, d'après les cas d'utilisation que l'on peut trouver dans les entreprises, sont les serveurs, le chargement des données en mémoire, etc...
Quant à la sécurité, je ne sais pas si elle est toujours garantie par rapport aux tiers, chose importante quand on travaille dans une architecture distribuée.
je veux simplement dire que
- c'est une porte ouverte à la bidouille
- sa présence témoigne de la volonté de combler des faiblesses.
Je pense que Sun devrait s'abstenir de ce genre de chose
qui ne peut que les décrédibiliser, mais je n'ai
pas étudié le package d'assez près pour être catégorique.
Je constate que, toi aussi, tu as un doute sur la sécurité de la chose.
------
Evidemment, puisque les types sont fixés à l'instanciation !En fait le code d'un template n'est compilé que si on réalise une instance de ce template. C'est un peu le point faible car tant qu'aucune instanciation n'est faite, il n'y a aucun moyen de vérifier le type (à chaque techno son inconvénient bien sur).
De toute façon, un code générique non instancié ne risque pas
plus de générer un erreur d'exécution qu'un programme pas encore écrit.
Et bien voila, on y vient! Je me souviens d'une argumentation de pro-Javapour ceux qui s'intéressent aux templates en java, il existe des projets en cours. http://igm.univ-mlv.fr/~forax/java/jlx/template/paper/Je crois que Sun, si ce n'est pas déjà fait, devrait s'inspirer de ces travaux de recherche qui sont très prometteurs.
il y a quelques années qui proclamait haut et fort que les templates ne servaient
à rien en java puisqu'on pouvait fourrer n'importe quel objet dans un conteneur.
Plein !!!! (dont un dont le nom commence par J et finit par a).A bon tu connais bcp de langage qui ne sont pas extensibles?Ceci montre que la véritable puissance d'un langage est avant tout d'être extensible.
Tu vois qu'il n'y a pas que les performances dans la vie.
Un langage extensible est un langage dans lequel ce que tu développes ne peut
pas être distingué de ce qui existait avant.
Un exemple frappant est FORTH : tu peux tout redéfinir (même les structures de contrôle
en étant habile), et tout ce que tu as développé s'utilise comme du natif. LISP est un
autre exemple, mais ces deux langages ont en commun une syntaxe extrêmement frustre,
et d'autres caractéristiques ce qui en limitent l'usage.
En ce qui concerne C++, les types que tu peux définir s'utilisent exactement
comme les types natifs (même syntaxe, même façon de les passer en paramètres,
interface pouvant être basée sur des opérateurs, etc.)
Leurs performances sont également très proches (tu vois que les perf, dans la vie,
ça sert, même si il n'y a pas que ça -effectivement-)
C++ permet également de définir des opérateurs de conversion, etc.
Tout ceci fait que les types que tu définis sont absolument indiscernables des types
natifs.
L'extensibilité c'est ça, et Java ne le fait pas.
L'extensibilité, c'est aussi de pouvoir implémenter facilement des
fonctionalités qui nécessiteraient autrement une modification des structure
de contrôle du langage.
Par exemple, C++ utilise un concept tout simple, mais très utile : le destructeur.
Regardes de près Jthreads++ et tu verra qu'il est utilisé pour implémenter les
sections critiques (synchronized en Java).
Voila un concept qui a été écarté dans la conception de Java, et qui pourtant
remplace a lui seul synchronized, finalize() et finally.
Pas mal pour un truc qui ne sert a rien.
(Voir dans les post antérieurs mes interventions à ce sujet).
L'extensibilité, c'est ça et Java ne le permet pas.
L'extensibilité, c'est aussi que les extensions n'épuisent pas le programmeur
qui les utilise et la machine qui les exécute.
Lorque je vois les sinistres bidouilles qu'il faut faire pour
donner à un "int" une très vague sémantique objet, je pleure :
conversion en int->Integer, puis Integer->int pour la moindre opération,
puis retour en Integer, et vlan, la JVM pédale à chaque conversion !
L'extensibilité, c'est ça et Java ne l'offre pas.
J'espère que tu ne veux pas dire que les concepteurs de Java ont inventé les threads ?En plus sans java, JThread n'existerait pas, on peut donc reconnaitre que java propose de bonne idées en programmation.
Il s'agit de mise en oeuvre d'un concept qui existaient et avait été implémenté bien avant.
Le nom Jthreads++ est un nom "commercial" qui rappelle que les fontionnalités sont identiques
et c'est tout. J'ai fait pendant longtemps des threads en C (pas C++) : c'était beaucoup moins
commode qu'en Java, mais ça marchait. Il se trouve qu'en C++, c'est aussi commode et qu'il
n'y a pas eu besoin pour cela de modifier le langage.
Ben .. d'accord, mettons que je m'en fiche aussi,J'affirme qu'en moyenne, on peut s'attendre à obtenir 80 à 100% des performances du c++ optimisé. Maintenant dans l'application que je développe, je ne vais pas m'amuser à la faire en c++ pour le plaisir de faire du benchmark, je m'en fous.
mais d'ou sortent les 80 à 100% si tu n'as pas essayé ?
De toute façon le problème réel est ci-dessous.
Le librairie open GL est *appelée* au travers de JNI (interface avec du code natif)Evidemment la librairie opengl pour java est réalisée avec jni. Lors de l'exécution, le JIT optimise les accès comme si ils étaient en natif. Donc les appels de méthodes opengl se font à la même vitesse qu'en c++. Maintenant la perte de performance se fait dans la gestion de la mémoire, d'ou les optimisation que je donne. De plus, il est possible d'améliorer le système de chargement des textures avec nio.Il est notoire que les calculs 3D coûtent cher et doivent
donc représenter une part importantes des temps d'exécution.
Je me demande donc si vous n'avez pas mesuré les performance d'open GL
(qui ne doit pas être écrit en Java, et peut d'ailleurs largement reposer
sur le matériel) au lieu de celle de votre code.
Avez vous profilé l'appli pour voir ou se passe le temps d'exécution ?
Quant au profilage, ma foi, il est évident que le goulot d'étranglement est ici la capacité de la carte graphique. TOUS les calculs sont effectués par opengl, donc en natif.
Si je veux distribuer mon appli, il faut que je fournisse une dll pour windows, une librairie pour linux, pour beos, etc.. qui sont fournies
elle n'est pas réalisée *avec* JNI; c'est plus qu'une nuance, ça n'a rien à voir.
Ce que je supposais se vérifie donc, ton appli exécute du code natif (en
proportion inconnue).
Le temps que tu as mesuré ne concerne donc pas du code Java mais du code C ou C++
encapsulé par une surchouche Java. En fait, c'est même peut-être plus compliqué
si des opérations sont faites par hardware.
Je trouve assez fort, et carrément non scientifique de prétendre mesurer la rapidité
d'un langage de cette manière (c-a-d en exécutant du code écrit dans un autre langage)
Par exemple: (et ce n'est qu'un exemple car je ne connais pas les chiffres réels)
Supposons que dans une appli C++ utilisant OpenGL, 90% du temps soit consommé
par openGL et 10% ailleurs (ça me semble être une hypothèse minimale puisque
tu dis que TOUS les calculs sont faits par openGL.)
Sur 100s on passe donc
90s en OpenGL 10s ailleurs.
Recodons la partie non openGL en Java et *supposons* que celle ci soit 5 fois plus lente
on obtient donc
90s en OpenGL 50s ailleurs, soit 140s c-a-d seulement 1,4 fois le temps initial
ce qui est en contradiction avec notre hypothèse de départ (5 fois).
Ce type de test ne mesure donc absolument pas les perf du langage.
On va me rétorquer qu'on en a rien à faire puisque, de toute façon on récupère bien 80à90%
des perf du C++ pur. Manque de pot, on à perdu au passage tout ce qui fait l'intérêt de Java
a) la simplicité puisqu'on est obligé de se prendre la tête avec des optimisations,
des accès direct à je ne sais quoi, des transformations de tables Java en tables natives, etc.
b) le programme n'a plus l'universalité que devrait fournir la JVM, puisque tu dois fournir
les bibli openGL (DLL ou .so) pour qu'il tourne. Il se trouve exactement dans la même
situation que n'importe quel programme compilé, en C++ ou autre, ce qui fait s'effondrer
tout le modèle java.
Vrai ou faux ?
Je crois qu'il ne faut pas avancer comme cela des chiffres qui, si ils
ne sont pas faux en eux mêmes, ne représentent pas ce qu'ils sont censés
représenter. Je pense sincérement qu'ils ont été pris pour argent comptant
et contribuent à alimenter la rumeur.







Répondre avec citation









Partager