Get jChecs at SourceForge.net. Fast, secure and Free Open Source software downloads
Divers
Optimisation

Cette page résume et commente quelques mesures des performances de J2SE 6 effectuées lors du développement de jChecs.

Même si la véritable optimisation reste de choisir le bon algorithme et si jChecs n'a pas pour but d'être optimal, ceci peut fournir des pistes pour optimiser le codage final d'un algorithme en fonction de ce nouvel environnement...

Toutes les mesures ont été prises avec la JVM 6 (beta 104) de Sun pour Linux, sans option particulière.

Une mesure est prise en référence (en gras) pour chaque série et les autres résultats sont donnés comparativement : le plus grand nombre est le meilleur.

Boucles
for (en avant) 100%
Les boucles inversées (décrémentées) n'ont plus vraiment d'intérêt avec cette JVM.
Un « while » en avant (incrémenté) reste moins performant que le « for » équivalent.
for (en arrière) 100%
while (en avant) 75%
while (en arrière) 100%
Variables
Statique 100%
Les temps d'accès aux différents types de variables deviennent comparables, mais les variables statiques restent les plus lentes.
Instance 128%
Locale 131%
Autoboxing
int / new Integer(int).intValue() 100%
  • Les constructeurs, supposés archaïques, restent plus rapides que les nouvelles méthodes de fabriques des types simples.
  • L'autoboxing a un coût négligeable sur les performances.
  • Les types primitifs sont nettement plus rapides...
int / Integer.valueOf(int).intValue() 95%
int / Integer (Autoboxing) 94%
int / int 5 688%
Allocation de tableaux
Tableaux d'objets
  • L'allocation de tableaux est quasiment aussi rapide pour les objets que pour les types primitifs.
  • A nombres d'éléments égaux, il est plus efficace d'allouer un tableau à une dimension qu'un tableau à n dimensions.
Le nombre d'éléments d'un tableau a un impact très fort sur les performances de l'allocation : ne pas allouer plus d'éléments que nécessaire.
Integer[64][64] 100%
Integer[64*64] 145%
Integer[32*64] 289%
Integer[0] 121 132%
Tableaux de primitives
int[64][64] 104%
int[64*64] 144%
int[32*64] 291%
int[0] 121 257%
Copie de tableaux
Tableaux d'objets
« System.arraycopy() » demeure la méthode la plus efficace pour copier des tableaux à une dimension, mais de très peu devant « Arrays.copyOf() ».
  • Ne pas utiliser de boucle pour recopier des tableaux, surtout d'objets.
  • Les boucles inversées (décrémentées) sont à éviter lors d'accès consécutifs aux éléments d'un (grand) tableau.
System.arraycopy(Integer) 100%
Arrays.copyOf(Integer) 99%
for (Integer, en avant) 49%
for (Integer, en arrière) 37%
Tableaux de primitives
System.arraycopy(int) 100%
Arrays.copyOf(int) 100%
for (int, en avant) 95%
for (int, en arrière) 91%
Parcours de listes d'éléments
ArrayList d'objets
  • Le moyen le plus efficace pour parcourir une « ArrayList » est une boucle réalisant des accès indexés (des « get() »).
  • Le moyen le plus efficace pour parcourir un « Vector » est d'utiliser son énumérateur.
  • La forme étendue du « for », introduite avec J2SE 5.0, est optimale pour parcourir les éléments d'un tableau.
  • Les tableaux demeurent plus rapides que les collections, et les primitives plus rapides que les objets.
  • Parcourir à l'envers une liste d'éléments a toujours un impact négatif sur les performances.
  • Un « Vector », synchronisé et donc théoriquement plus lent, se montre pourtant plus efficace qu'une « ArrayList » dans ce cas.
for sur Enumeration (Java 1.0) 100%
while sur Enumeration (Java 1.0) 100%
for sur Iterator (Java 1.2) 132%
while sur Iterator (Java 1.2) 133%
for étendu (J2SE 5.0) 121%
Accès indexés (get, en avant) 205%
Accès indexés (get, en arrière) 163%
Vector d'objets
for sur Enumeration (Java 1.0) 218%
while sur Enumeration (Java 1.0) 218%
for sur Iterator (Java 1.2) 161%
while sur Iterator (Java 1.2) 161%
for étendu (J2SE 5.0) 160%
Accès indexés (get, en avant) 208%
Accès indexés (get, en arrière) 167%
Tableau d'objets
for étendu (J2SE 5.0) 403%
Accès indexés (get, en avant) 391%
Accès indexés (get, en arrière) 313%
Tableau de primitives
for étendu (J2SE 5.0) 1 325%
Accès indexés (get, en avant) 1 211%
Accès indexés (get, en arrière) 960%
Concaténation de chaînes
Chaînes variables
Utiliser un « StringBuilder » est le moyen le plus performant pour concaténer des chaînes calculées à l'exécution.
La concaténation de chaînes constantes est plus performante avec des « String », car pré-calculée à la compilation.
String 100%
StringBuffer 109%
StringBuilder 111%
Chaînes constantes
String 381%
StringBuffer 220%
StringBuilder 223%
Types génériques
Lecture
Une vérification de type par rapport à la variable cible est introduite à l'éxécution, et donc réduit les performances, si la cible n'est pas déclarée avec le même type que la source ou comme « Object ».
Integer = List<Integer> 100%
Integer = List<Object> 97%
Integer = List<? super Number> 95%
Object = List<Integer> 112%
Object = List<Object> 119%
Object = List<? super Number> 113%
Ecriture
List<Integer> = Integer 93%
List<Object> = Integer 94%
List<? super Number> = Integer 94%