title: Hashmap put performance varies based on keys
body: <p>I am trying to load around 5 million objects fetched from DB via hibernate into a hashmap. I do this for 2 types of classes (A &amp; B). I iterate through the pojos. Key is a field from the pojo and the value is the pojo itself. 
  <br><br>1. For class A type, the key is an integer field. I am able to load the map in less than 20 seconds. 
  <br><br>For class B<br>2.a) Test 1, my key is a String field. When I try to load these objects to a new hashmap (fresh attempt by restarting the java process, so no concern of GC yet), it takes about 30 seconds to load 100K objects into the map. <br>2.b) Test 2, when i try to use a different field from this class (integer type) and load the map, it works like the 1st one and loads in less than 20 seconds.
  <br>2.c)Test 3, I wondered if the problem was the data type. So for class B, i tried another approach of creating a string key using the integer field in #2.b. (key = int_field + "") and it loaded in &lt; 20 seconds. </p>
  
  <p>Another test, Test 4, that I did for class type B was the way i created the key. For 2.c, I created the key like this <br>
      <b><i>map.put( pojo.getIntField() + "", pojo);</i></b>
  <br>Result was as mentioned above in 2.c
  <br><br>
  2.d) But when I created another getter in the pojo that returned <b>int_field + ""</b> and used this in the map put as<br>
  <b><i>map.put( pojo.getIntFieldInStringForm(), pojo);</i></b>
  <br>
  The performance deteriorated to around 30 secs for 100K objects.
  <br><br>I know the problem is with the keys because I have verified the db fetch phase by adding the result objects into a list and it loads in &lt; 20 secs for both types.</p>
  
  <p>I am not able to understand the reason for this. If anyone can please shed some light on this, it would be really helpful. Much appreciated. Thanks</p>
  
  <p>Edited:
  Adding code snippets here (Forgive the formatting/typos if any):
  <br>Test for #1<br></p>
  
  <pre><code>Map&lt;String, ClassA&gt; map = new HashMap&lt;String, ClassA&gt;();
  Session session = sessionFactory.openNewSession();
  try {
      Iterator&lt;ClassA&gt; iterator = session.createQuery( "from ClassA" ).setFetchSize( 1000 ).iterate();
      while ( iterator.hasNext() ) {
          ClassB objClassA = iterator.next();
          map.put( objClassB.getIntField(), objClassA );              
      }
  }
  catch (Exception e) {
      e.printStackTrace();
  }
  finally {
      session.close();
  }
  </code></pre>
  
  <p><br>Test for #2.a<br></p>
  
  <pre><code>Map&lt;String, ClassB&gt; map = new HashMap&lt;String, ClassB&gt;();
  Session session = sessionFactory.openNewSession();
  try {
      Iterator&lt;ClassB&gt; iterator = session.createQuery( "from ClassB" ).setFetchSize( 1000 ).iterate();
      while ( iterator.hasNext() ) {
          ClassB objClassB = iterator.next();
          map.put( objClassB.getStringField(), objClassB );               
      }
  }
  catch (Exception e) {
      e.printStackTrace();
  }
  finally {
      session.close();
  }
  </code></pre>
  
  <p><br>Test for #2.b<br></p>
  
  <pre><code>Map&lt;Integer, ClassB&gt; map = new HashMap&lt;Integer, ClassB&gt;();
  Session session = sessionFactory.openNewSession();
  try {
      Iterator&lt;ClassB&gt; iterator = session.createQuery( "from ClassB" ).setFetchSize( 1000 ).iterate();
      while ( iterator.hasNext() ) {
          ClassB objClassB = iterator.next();
          map.put( objClassB.getIntField(), objClassB );              
      }
  }
  catch (Exception e) {
      e.printStackTrace();
  }
  finally {
      session.close();
  }
  </code></pre>
  
  <p><br>Test for #2.c<br></p>
  
  <pre><code>Map&lt;String, ClassB&gt; map = new HashMap&lt;String, ClassB&gt;();
  Session session = sessionFactory.openNewSession();
  try {
      Iterator&lt;ClassB&gt; iterator = session.createQuery( "from ClassB" ).setFetchSize( 1000 ).iterate();
      while ( iterator.hasNext() ) {
          ClassB objClassB = iterator.next();
          map.put( objClassB.getIntField() + "", objClassB );             
      }
  }
  catch (Exception e) {
      e.printStackTrace();
  }
  finally {
      session.close();
  }
  </code></pre>
  
  <p><br>Test for #2.d<br></p>
  
  <pre><code>Map&lt;String, ClassB&gt; map = new HashMap&lt;String, ClassB&gt;();
  Session session = sessionFactory.openNewSession();
  try {
      Iterator&lt;ClassB&gt; iterator = session.createQuery( "from ClassB" ).setFetchSize( 1000 ).iterate();
      while ( iterator.hasNext() ) {
          ClassB objClassB = iterator.next();
          map.put( objClassB.getIntFieldInStringForm() + "", objClassB );             
      }
  }
  catch (Exception e) {
      e.printStackTrace();
  }
  finally {
      session.close();
  }
  </code></pre>