compareTo() vs equals() - Java - Programmation
Marsh Posté le 12-11-2010 à 10:03:15
D'après la doc, par exemple http://leepoint.net/notes-java/dat [...] jects.html , il semble que equals() soit plus primitif que compareTo(), et donc soit plus rapide, mais c'est à vérifier par des mesures. En matière d'optimisation, il vaut toujours mieux mesurer que spéculer.
J'en pense que, si la vitesse est un critère important, on peut écrire ce bout de programme en C ou en assembleur, au lieu de Java, car Java est forcément plus lent, à cause de la couche de la JVM et des objets. En général, on cherche les bugs plutôt que les gains de micro-secondes. Une règle général dit que les opérations en mémoire sont très rapides, celles avec des I/O sur disque sont plus lentes, et celles sur le réseau sont lentes aussi, donc il faut optimiser ces deux dernières sortes d'opération, plutôt que les opérations locales.
Marsh Posté le 12-11-2010 à 14:24:38
equals dit que tu veux savoir si deux objets sont égaux (et renvoie un booléen), compareTo non.
À ton avis, est-il plus lisible de voir if(a.equals(b)) ou if(a.compareTo(b) == 0).
Tu as ta réponse sur lequel utiliser. Parler des performances de equals et compareTo, surtout sur les types de la stdlib, c'est de la branlette de bas étage.
Marsh Posté le 14-11-2010 à 10:38:48
olivthill a écrit : En matière d'optimisation, il vaut toujours mieux mesurer que spéculer. |
suivi d'un malheureux :
olivthill a écrit : car Java est forcément plus lent |
Marsh Posté le 14-11-2010 à 10:53:03
mask> Je dirais que c'est moins une question de lisibilité que de sémantique de l'opération.
Pour Integer, equals est consistent avec l'ordre naturel et la question se réduit à la lisibilité et/ou aux performances, mais ce n'est pas forcément le cas avec toutes les classes.
On peut parfois avoir :
Code :
|
La sémantique doit primer sur la lisibilité et les éventuelles différences de perf si on veut un résultat correct!
Marsh Posté le 14-11-2010 à 22:53:06
Citation : suivi d'un malheureux : |
Vous profitez du laxisme des modérateurs.
Pourquoi intervenir pour une critique négative ? Et surtout une critique sans aucun argument ? C'est un coup de pied lâche et gratuit.
En plus, c'est faux, Java est plus que lent que le C.
Moi, je suis sérieux, j'argumente, par exemple en citant un extrait de http://info-rital.developpez.com/t [...] /pourquoi/ :
Citation : Les programmes utilisant les premières versions de la JVM étaient entre 20 et 40 fois plus lents que leur équivalents en C par exemple. Tout simplement car le Java Byte Code était interpreté par la machine virtuelle. Or par définition, une code interprété est plus lent qu'un code natif. Mais c'était en 1993...A partir de 1995, Sun a incorporé la technologie HotSpot, un compilateur JIT (Just-In-Time) dans ses JVM. Il s'agit en fait d'une autre étape de la compilation, mais dont vous n'avez pas à vous occuper. |
Marsh Posté le 15-11-2010 à 13:38:46
Que l'exécution du programme en langage Java soit un peu plus lent que son homologue développé en C/C++ est une réalité dans de nombreux cas.
Par conte le propos est que certaines prétendues optimisations feront gagner des miettes en terme de performance mais rendront le code difficilement lisible.
Marsh Posté le 15-11-2010 à 14:09:44
Le fait qu'en moyenne un programme java soit plus lent qu'un programme C++, ce n'est qu'un effet de bord du niveau moyen d'un programmeur Java vis à vis du niveau moyen d'un programmeur C++, non?
A+,
Marsh Posté le 15-11-2010 à 16:30:16
C'est clair, suffi de voir le nombre de boulets qui posent dans la cat C/C++ parce qu'ils ont "perdu" leurs pointeurs pour s'en rendre compte
Marsh Posté le 16-11-2010 à 08:56:57
Bande de trolls gluants... Mais que fait la modération?
Marsh Posté le 16-11-2010 à 10:20:10
Sinon pour en revenir à la question d'origine :
Code :
|
Code :
|
En conclusion, equals est plus performant et est préférable du point de vue de la lisibilité du code et de la sémantique.
Marsh Posté le 16-11-2010 à 10:25:25
Bidem a écrit :
En conclusion, equals est plus performant et est préférable du point de vue de la lisibilité du code et de la sémantique. |
init : 127 ms |
> java -version |
Et si je remplace l'init par:
Code :
|
init : 449 ms |
Marsh Posté le 16-11-2010 à 11:59:01
J'ai réessayé avec ton init et ça ne change pas grand chose à mes résultats :
Code :
|
NB : PC pas très puissant sur un Windows 32 bits
Code :
|
On peut donc supposer que ça vient du fait que tu ais une JVM 64 bits.
Je réessayerai ce soir sur un PC plus puissant (32 bits aussi) mais je doute que ça puisse inverser la tendance.
Marsh Posté le 16-11-2010 à 12:04:55
Bidem a écrit : On peut donc supposer que ça vient du fait que tu ais une JVM 64 bits. |
Yup, ça a l'air d'être ça:
> java -version |
Marsh Posté le 16-11-2010 à 14:02:27
A mon avis c'est pas tant le fait que ce soit 64 bits que la différence entre les optimisations internes JVM Client VS JVM Server
Marsh Posté le 16-11-2010 à 14:11:44
esox_ch a écrit : A mon avis c'est pas tant le fait que ce soit 64 bits que la différence entre les optimisations internes JVM Client VS JVM Server |
Quoi qu'ils dise, ça fait tourner la JVM client par défaut, j'ai testé en forçant `-client`, d'où le test en `-server` derrière.
Marsh Posté le 17-11-2010 à 20:59:57
Bidem a écrit : |
C'est faux pour la partie en gras. Avec Integer, cela ne fait sans doute pas de différence, mais avec d'autres types, il faut utiliser compareTo pour vérifier une relation d'ordre.
Marsh Posté le 17-11-2010 à 21:24:03
sircam a écrit : |
Sauf qu'on veut pas une relation d'ordre là, on veut juste une égalité.
Marsh Posté le 17-11-2010 à 22:20:00
masklinn a écrit : |
C'est kif-kif dans le cas de BigInteger parce que equals() est consistant avec l'ordre naturel, mais ce n'est pas généralisable à tous les types numériques. C'est sur ce piège que portais ma remarque avec certains types infâmes :
|
dans ce cas, seul compareTo() peut vérifier une égalité de valeur numérique et possède la sémantique correcte.
Je trouve ça moins confortable d'utiliser equals() avec certains types parce que ça tombe bien mais compareTo() avec d'autres parce qu'on n'a pas le choix, alors que compareTo() est correct partout. Mais bon, hein, equals est très bien ici.
Marsh Posté le 17-11-2010 à 22:23:04
sircam a écrit :
|
Ouais enfin si compareTo est défini et equals pas, faut pas utiliser compareTo, faut défoncer le mec qui a écrit la classe à coup de batte.
Marsh Posté le 17-11-2010 à 22:47:16
masklinn a écrit : |
Beh tu peux avoir equals et compareTo parfaitement définis, et les deux relations que j'ai décrites (ordre naturel pas consistant avec equals)... le tout livré dans java.math.
Y'a pas forcément moyen de faire autrement dans certains cas.
Marsh Posté le 21-11-2010 à 10:23:47
Bidem a écrit : Sinon pour en revenir à la question d'origine :
|
Voilà un message très intéressant et je te remercie d'avoir pris le temps de répondre à ma question avec autant d'arguments.
J'ai lancé ton test sur mon boulier et j'ai des résultats similaires en ce qui concerne les performances (java 1.6.21 64 bits). D'ailleurs la différence entre equals() et compareTo() augmente avec le nombre de comparaisons, ce qui prouve que ce n'est pas un simple offset. Cependant, l'argument sémantique soutenu par certain me semble aussi pertinent. Je suis convaincu que la lisibilité (et donc la capacité du programme a être vérifié) prime sur la performance (à quelque rares exceptions près). Qui s'intéresse à un programme rapide qui retourne des conneries ?
Merci encore pour tes explications éclairantes !
Marsh Posté le 21-11-2010 à 10:33:08
sircam a écrit : mask> Je dirais que c'est moins une question de lisibilité que de sémantique de l'opération.
|
Mon inculture en informatique est grande je le reconnais, aussi je n'arrive pas à imaginer d'exemple ou les deux expressions booléennes ci-dessus seraient vraies en même temps. Accepterais-tu de m'en dire un peu plus s.t.p. ? Dans quel cas pourrait-on avoir a.compareTo(b) == 0 et pas a.equals(b) ? Sur des ensemble pour lesquels on n'aurait qu'un ordre partiel ?
D'avance merci pour tes explications éventuelles.
Marsh Posté le 21-11-2010 à 23:30:51
leonhard a écrit : |
Un exemple tout simple : imagine que tu as une classe Voiture et que tu décides de définir leur définir leur ordre par rapport à l'année de production.
a = New Voiture("Peugeot 206", 2010);
b = New Voiture("Citroen Xara", 2010);
Taadaaa !
Marsh Posté le 29-11-2010 à 09:08:02
Bidem a écrit : |
Ou plus évident encore : deux instances de BigDecimal avec des précisions différentes, par exemple 4.0 et 4.00!
Marsh Posté le 12-11-2010 à 09:03:42
Bonjour
Je suis en train de faire un petit programme qui utilise des objets de type BigInteger. Parfois je dois comparer si deux nombres sont égaux. Je me suis demandé si (dans le cas spécifique ou je garantis que les deux objets que je compare sont bien des BigInteger), il y a un avantage à utiliser la méthode equals() plutôt que la méthode compareTo(). Est-ce que l'une est plus efficace que l'autre ?
En regardant le code j'aurais tendance à penser que la méthode equals() est un petit peu plus rapide parce qu'elle ne doit pas s'occuper de l'ordre, mais vérifier s'il y a une différence. Qu'en pensez-vous ?
D'avance merci de votre aide et de vos conseils.