RSS Feed

Articles associés au tag ‘optimisation’

Parcourir un objet Map

2 April 2006 par SeB 4 commentaires »

Plusieurs solutions existent pour parcourir une interface Map. Mais sont-elles toujours optimales ?

En Java, l’interface Map permet de définir une liste d’association entre clés et valeurs. Ainsi à partir d’une clé, il est possible de retrouver la valeur correspondante.

Une bonne démarche pour parcourir un objet implémentant l’interface Map, est d’utiliser les itérateurs définis par l’interface Iterator. L’interface Map propose trois méthodes qui retournent une Collection à partir de laquelle il est possible d’accéder à un itérateur :

  • public Set entrySet(); retourne la liste des couples clé/valeur
  • public Set keySet(); donne la liste des clés
  • public Collection values(); permet d’obtenir la liste des valeurs

Lorsque l’on parcourt une Map, il est souvent nécessaire de connaître à la fois la clé et la valeur. Beaucoup de personnes sont alors tenté d’écrire[1] :

Map map;
for ( Iterator i = map.keySet().iterator(); i.hasNext();) {
 Cle cle = (Cle)i.next();
 Valeur valeur = (Valeur)map.get(cle);
 /* Utilisation des objets cle et valeur */
}

Ce bout de code fonctionne très bien. Pourtant il n’est pas optimal. En effet, on commence par récupérer la liste des clés. Puis pour chaque clé, on recherche la valeur correspondante. Or, il est préférable de récupérer en une seule passe les clés et les valeurs. Pour cela il faut faire appel à la méthode entrySet() :

Map map;
for ( Iterator i = map.entrySet().iterator(); i.hasNext();) {
 Entry couple = (Entry)i.next();
 Cle cle = (Cle)coupe.getKey();
 Valeur valeur = (Valeur)couple.getValue();
 /* Utilisation des objets cle et valeur */
}

Cet exemple, montre qu’il faut prendre le temps de lire la JavaDoc. Ceci afin d’utiliser de façon optimale l’API très riche offerte par le JDK. Ce type d’optimisation permet parfois de gagner énormément en performance. Car c’est le genre de boucle qui revient souvent dans le code source.

Notes

[1] Enfin, cet algorithme n’est pas rare…

 

String.equals() ou String.compareTo()

1 April 2006 par SeB 2 commentaires »

Plusieurs syntaxes existent pour comparer des objets String. Mais lequel faut-il utiliser ?

Tout d’abord, mettons de côté l’opérateur == qui compare si les références des deux objets pour vérifier s’ils correspondent à la même instance.

La méthode String.equals() vérifie l’égalité de deux chaînes de caractères. Alors que la méthode String.compareTo() calcule la différence entre deux chaînes de caractères. Il faut savoir que les deux test suivants sont équivalents[1] :

  • String str = "ma chaine";if ( str.equals("mot magic")) {/*...*/}
  • String str = "ma chaine";if ( str.compareTo("mot magic")==0) {/*...*/}

Laquelle de ces deux méthodes est la plus performante pour vérifier l’égalité ? Il paraît évident que la méthode equals doit être plus rapide que la méthode compareTo puisque la première doit s’arrêter dès qu’une différence est trouvée alors que la seconde calcule la différence. Or la méthode compareTo s’arrête également dès la première différence trouvée.

De plus, dans les anciennes version de Java, la méthode equals utilisait la méthode compareTo. Depuis elle a été optimisée et effectue ses contrôles elle-même. Par exemple, elle vérifie si les deux objets pointent sur la même instance ou bien si les chaînes de caractères ont la même longueur. Dans ces cas particuliers, la méthode equals se révèle nettement plus performante.

Par contre, pour des chaînes de caractères de même longueur et ne pointant pas sur la même instance[2], la méthode compareTo donne de bien meilleures performances[3].

Notes

[1] Moyennant quelques préconditions sur le caractère non nul des objets.

[2] Beaucoup d’objets String pointent sur la même instance contrairement à ce que l’on peut penser.

[3] Les mesures ont été réalisées avec Java 1.4.2 sous un environnement MS Windows.