juillet
2005
Integer i = Integer.valueOf(10);
sera dans la majorité des cas, plus performant.
La raison est que la méthode public static Integer valueOf(int i) {} implémente un cache pour les entiers entre -128 et 127, évitant de recréer de nouveaux objets Integer pour ces nombres.
En exécutant cette classe:
*
* @author Vincent
*/
public class Main {
/** Creates a new instance of Main */
public Main() {
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
loopNew();
loopAutoBoxing();
loopValueOf1();
loopValueOf2();
}
private static void loopNew() {
System.out.println("Start");
long start = System.currentTimeMillis();
for (int p = 0; p < 10000000; p++) {
for (int i = 0; i < 100; i++) {
Integer j = new Integer(i);
Integer k = new Integer(i+2);
Integer l = new Integer(i-1);
Integer m = new Integer(-(i+1));
}
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
private static void loopAutoBoxing() {
System.out.println("Start");
long start = System.currentTimeMillis();
for (int p = 0; p < 10000000; p++) {
for (int i = 0; i < 100; i++) {
Integer j = i;
Integer k = i+2;
Integer l = i-1;
Integer m = -(i+1);
}
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
private static void loopValueOf1() {
System.out.println("Start");
long start = System.currentTimeMillis();
for (int p = 0; p < 10000000; p++) {
for (int i = 0; i < 100; i++) {
Integer j = Integer.valueOf(i);
Integer k = Integer.valueOf(i+2);
Integer l = Integer.valueOf(i-1);
Integer m = Integer.valueOf(-(i+1));
}
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
private static void loopValueOf2() {
System.out.println("Start");
long start = System.currentTimeMillis();
for (int p = 0; p < 10000000; p++) {
for (int i = 200; i < 300; i++) {
Integer j = Integer.valueOf(i);
Integer k = Integer.valueOf(i+2);
Integer l = Integer.valueOf(i-1);
Integer m = Integer.valueOf(-(i+1));
}
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
}
J’obtiens les résultats suivants:
Start // new Integer(int i) avec i entre -128 et 127
40344 ms
Start // AutoBoxing ==> usage de valueOf(int i) avec i entre -128 et 127
14406 ms
Start // usage direct de valueOf(int i) avec i entre -128 et 127
13687 ms
Start // usage de valueOf(int i) mais avec i ayant toujours une valeur en dehors de la cache.
38594 ms
Que remarque-t-on ?
Que si on fait énormément de transformation de int en Integer pour des valeurs comprises entre -128 et 127, il vaut beaucoup mieux utiliser valueOf(int i) ou l’autoboxing. Les gains de performance sont énormes.
Si on utilise valueOf pour des valeurs non comprise dans le cache, on rejoint les temps de performance du new Integer(int i).
Lunatix ne voyait pas trop de différence dans son code, car il créait presque toujours des nombres en dehors du cache, et donc, ils étaient à chaque fois instancié.
Il est assez intéressant de noter que si on utilise la méthode valueOf(String s), il n’utilise pas le mécanisme de cache. En effet, la méthode valueOf(String s) contient le code suivant:
return new Integer(parseInt(s, 10));
Les programmeurs de chez Sun n’ont apparamment pas pensé à également utiliser le mécanisme de cache, en utilisant
return valueOf(parseInt(s, 10));
6 Commentaires + Ajouter un commentaire
Commentaires récents
Archives
- janvier 2012
- novembre 2010
- février 2009
- janvier 2009
- décembre 2008
- septembre 2008
- août 2008
- décembre 2007
- octobre 2007
- septembre 2007
- juillet 2007
- mai 2007
- avril 2007
- mars 2007
- février 2007
- janvier 2007
- décembre 2006
- novembre 2006
- octobre 2006
- septembre 2006
- août 2006
- juillet 2006
- juin 2006
- mai 2006
- avril 2006
- février 2006
- janvier 2006
- décembre 2005
- novembre 2005
- octobre 2005
- septembre 2005
- août 2005
- juillet 2005
- juin 2005
- mai 2005
- avril 2005
Catégories
- Certification
- Défis
- Devoxx
- Devoxx 2008
- Devoxx 2010
- Devoxx France 2012
- Divers
- Événements Java
- Fiches
- Hardware
- In English
- Java
- JavaDay 2006
- JavaFX
- JavaOne 2005
- JavaOne 2006
- JavaOne 2007
- Javapolis 2005
- Javapolis 2006
- Javapolis 2007
- JBoss
- Livres
- Mac
- NetBeans
- OpenJDK
- Pensée
- Performance
- Perles
- Sun Tech Days Paris 2007
- Traduction
>attention que l’instantiation d’un objet est TRES couteuse en temps !!!
héhé ok, mais alors que pour les valeurs entre -128 et +127
A propos de valueOf :
If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values.
…donc pour eux, c’est juste parce que ce sont des valeurs courantes :p
Pour JMax:
attention que l’instantiation d’un objet est TRES couteuse en temps !!!
Pour Lunatix:
Modifie ton code comme suit
for (int i = 0; i < 100; i++) { <br />
Integer j = new Integer(i); <br />
Integer k = new Integer(i+2); <br />
Integer l = new Integer(i-1); <br />
Integer m = new Integer(i+1); <br />
} <br />
}
Et compare les deux sur ta machine. Tu devrais remarquer une différence TRES significative.
Pour adiGuba:
Oui, c’est seulement depuis JDK 5. Et La cache est limitée aux nombres entre -128 et +127.
Personellement, j’aurais caché entre 0 et 255 car, dans la majorité des cas, on n’utilise que des nombres positifs pour les index. Mais je suppose que s’ils ont choisi -128 et +127, c’est qu’ils avaient leur raison. Mais j’aimerais tout de même connaitre la justification. Juste par curiosité.
Personnellement en voyant le code source je dirais que la version
est en générale plus « performante » en nombre d’instructions effectuées
this.value = value; <br />
}
il faut cependant voir qu’il y a bien un cache avec la version valueOf mais seulement pour des entiers compris entre -128 et +127
final int offset = 128; <br />
if (i >= -128 && i
Personnellement en voyant le code source je dirais que la version
est en générale plus « performante » en nombre d’instructions effectuées
public Integer(int value) <br />
{ <br />
this.value = value; <br />
} <br />
il faut cependant voir qu’il y a bien un cache avec la version valueOf mais seulement pour des entiers compris entre -128 et +127
public static Integer valueOf(int i) { <br />
final int offset = 128; <br />
if (i >= -128 && i
si je fais
for (int i = 0; i < 10000; i++) { <br />
Integer j = new Integer(i); <br />
Integer k = new Integer(i+2); <br />
Integer l = new Integer(i-1); <br />
Integer m = new Integer(i+1); <br />
} <br />
}
et son equivalent avec l’autre conversion…
j’obtient 149109 et 151563ms… en clair c’est kif kif quoi
Salut,
Il me semble que valueOf() gère un cache, ce qui fait qu’il doit être plus rapide si on utilise plusieurs fois les mêmes valeurs…
Mais avec des valeurs différentes ce doit être kif-kif…
Au fait, valueOf(int) c’est depuis Java 5.0 seulement et c’est ce qui est utilisé par l’autoboxing :
est compilé comme :
a++