2010-08-06 4 views
2

Supposons que j'exécute l'un des extraits de code ci-dessous pour une liste de 1000 entrées Event (dans allEventsToAggregate). Est-ce que je verrais une amélioration des performances dans la première implémentation si les événements dans allEventsToAggregate sont triés par customerId, avec chaque client ayant environ 3 événements? C'est essentiellement une question de comparaison de chaîne par rapport à la performance de recherche HashMap.Performances des comparaisons de chaînes supplémentaires par rapport aux recherches HashMap

Option 1:

Map<String, List<Event>> eventsByCust = new HashMap<String, List<Event>>(); 
List<Event> thisCustEntries; 
String lastCust = null; 
for (Event thisEvent : allEventsToAggregate) { 
    if (!thisEvent.getCustomerId().equals(lastCust)) { 
     thisCustEntries = eventsByCust.get(thisEvent.getCustomerId()); 
     if (thisCustEntries == null) { 
      thisCustEntries = new ArrayList<Event>(); 
     } 
    } 
    thisCustEntries.add(thisEvent); 
    eventsByCust.put(thisEvent.getCustomerId(), thisCustEntries); 
    lastCust = thisEvent.getCustomerId(); 
} 

Option 2:

Map<String, List<Event>> eventsByCust = new HashMap<String, List<Event>>(); 
for (Event thisEvent : allEventsToAggregate) { 
    List<Event> thisCustEntries = eventsByCust.get(thisEvent.getCustomerId()); 
    if (thisCustEntries == null) { 
     thisCustEntries = new ArrayList<Event>(); 
    } 
    thisCustEntries.add(thisEvent); 
} 

Répondre

3

Est-ce que je vois une amélioration de la performance

Presque certainement pas. À moins que ce bloc ne représente une boucle interne critique de votre application, tout gain de performance marginal sera presque certainement imperceptible.

Par conséquent, je voudrais aller avec la deuxième version du code, car c'est une expression plus claire de votre intention et sera donc plus facile à maintenir (tout en étant légèrement moins enclin aux bugs subtils en premier lieu). La maintenabilité l'emporte presque certainement sur l'application de 0,001% plus rapidement.

+1

C'est aussi ma pensée. Juste pour la curiosité, je me demande à quel point ce serait important. Que se passerait-il si les morceaux des clients étaient autour de 1000 chacun, et que mes records totaux étaient de 1 million? – pkananen

+0

@pkananen: Le point auquel il importe, est le point où le profilage de l'application montre qu'il passe une quantité non négligeable de temps dans ce morceau particulier de code, et vous 1) devez accélérer les choses, et 2) ne peut pas obtenir autant de «bang pour votre argent» en optimisant les autres hotspots. ;-) –

+0

Oui, je suis d'accord. C'était plus d'une question théorique. – pkananen

2

1) Rappelez-vous qu'une récupération réussie d'un élément à partir d'un HashMap nécessite une comparaison de chaînes pour confirmer que vous avez vraiment trouvé le bon article.

2) Nous semblons parler de très petites différences dans le temps d'exécution, pas de réelles améliorations algorithmiques. Est-ce vraiment utile de perdre la lisibilité pour ça?

3) Pour les petites différences, la seule façon de vraiment savoir sera de réellement chronométrer la chose en pratique - en fait non seulement pour faire une comparaison, mais pour l'organiser comme une expérience scientifique à part entière. Il y a aussi trop à se soucier de ce que votre compilateur et votre système d'exécution ont choisi d'optimiser, de ce que signifie la mise en cache des cpu ou les failles de la VM, et ce que la garbage collection de Java pense de votre algorithme. Ensuite, bien sûr, vous trouverez peut-être que vous obtenez des réponses différentes pour différentes versions de Java ou sur du matériel avec différentes CPU, cartes mères ou tailles de mémoire, ou même combien de temps le système a fonctionné et combien de temps il a dû migrer son contenu de disque dans le cache de la mémoire, ou compiler JIT-bits pertinents de Java, ou autre.

Questions connexes