Pourquoi créer un HashMap plus rapidement que créer un object ?

J’ai essayé de créer ma propre carte pour améliorer les performances dans un environnement spécial, et j’ai réalisé quelque chose de très intéressant: créer un new Hashmap(2000) est plus rapide que le new Object[2000] . ordre j’exécute ces commandes. C’est assez déroutant pour moi, surtout car le constructeur Hashmap contient une table = new Entry[capacity] , en fonction de cela . Y a-t-il quelque chose qui ne va pas avec mon banc d’essai?

 public static void test(int amm){ //amm=1_000_000 Map m1 = null; Object[] arr = null; long time = System.nanoTime(); for(int i = 0; i < amm; i++){ m1 = new HashMap(2000); } System.out.println("m1: " + (System.nanoTime() - time)); //m1: 70_455_065 time = System.nanoTime(); for(int i = 0; i < amm; i++){ arr = new Object[2000]; } System.out.println("arr: " + (System.nanoTime() - time)); //arr: 1_322_473_803 } 

J’aimerais voir les résultats des tests sur un autre ordinateur. Je n’ai aucune idée pourquoi la création d’un HashMap est 10 fois plus rapide que la création d’un Object[] .

Si vous regardez l’implémentation de HashMap , le constructeur ressemble à:

 public HashMap(int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity); if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; if (loadFactor <= 0 || Float.isNaN(loadFactor)) throw new IllegalArgumentException("Illegal load factor: " + loadFactor); this.loadFactor = loadFactor; threshold = initialCapacity; init(); } 

Et init() ressemble à:

 /** * Initialization hook for subclasses. This method is called * in all constructors and pseudo-constructors (clone, readObject) * after HashMap has been initialized but before any ensortinges have * been inserted. (In the absence of this method, readObject would * require explicit knowledge of subclasses.) */ void init() { } 

Donc, initialCapacity ne initialCapacity pas à créer un tableau. Où est-il utilisé? Regardez la méthode put()

 public V put(K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); } // hidden } 

En faisant un put, le tableau est réellement créé. Je n'ai pas montré inflateTable() mais il fait des calculs et initialise le tableau.

Un object HashMap vide est beaucoup plus petit qu’un tableau de références 2000 Object . Même si vous passez 2000 au paramètre HashMap constructeur HashMap , cela ne crée pas encore 2000 espaces pour les objects.