the serialized size doesnt have to be that different if you use Integer key
objects because hashmap has its own special serialization where it doesnt
have to store everything thats in mem
but just the key/value combination
But in memory we have an Entry object:
HashMap.Entry implements Map.Entry {
final Object key;
Object value;
final int hash;
Entry next;
IntHashMap.Entry
{
final int key;
Object value;
Entry next;
so you see thats one reference less per entry.
Also the lookup could be faster because it doesnt have to calculate the hash
on for example strings.
The IntHashMap just skips over the object key hash and gives you the option
to give that hash yourself.
This only works ofcourse for the same type of objects where the hash is
always different for any object, so it wont work as a replacement of String
key, but it does for Integer key
johan
On Fri, Feb 13, 2009 at 09:43, Tuomas Kärkkäinen <[email protected]>wrote:
> Hi,
>
> I couldn't gather from the javadoc when IntHashMap should be preferred over
> a regular HashMap, i.e. how many objects per map, what type of objects etc.
>
> I wrote a little program (copy pasted at the bottom) to see how much the
> size difference was for IntHashMap, java.util.HashMap and
> java.util.concurrent.ConcurrentHashMap.
>
> for 1 instance of new org.apache.wicket.Page(){};
> for 10 instances of new org.apache.wicket.Page(){};
> for 100 instances of new
> org.apache.wicket.ajax.form.AjaxFormSubmitTestPage();
>
> Br,
> Tuomas
>
> the results are as follows, respectively:
>
> --------------------------------------------------
>
> map implementation: org.apache.wicket.util.collections.IntHashMap -- size
> of outputstream: 54 bytes.
> map implementation: java.util.HashMap -- size of outputstream: 57 bytes.
> map implementation: java.util.concurrent.ConcurrentHashMap -- size of
> outputstream: 282 bytes.
> HashMap is 5.556% larger than IntHashMap.
> ConcurrentHashMap is 422.222% larger than IntHashMap.
>
> --
>
> map implementation: org.apache.wicket.util.collections.IntHashMap -- size
> of outputstream: 369 bytes.
> map implementation: java.util.HashMap -- size of outputstream: 399 bytes.
> map implementation: java.util.concurrent.ConcurrentHashMap -- size of
> outputstream: 624 bytes.
> HashMap is 8.130% larger than IntHashMap.
> ConcurrentHashMap is 69.106% larger than IntHashMap.
>
> --
>
> map implementation: org.apache.wicket.util.collections.IntHashMap -- size
> of outputstream: 24272 bytes.
> map implementation: java.util.HashMap -- size of outputstream: 24572 bytes.
> map implementation: java.util.concurrent.ConcurrentHashMap -- size of
> outputstream: 24797 bytes.
> HashMap is 1.236% larger than IntHashMap.
> ConcurrentHashMap is 2.163% larger than IntHashMap.
>
>
> ----------
>
> /*
> * Licensed to the Apache Software Foundation (ASF) under one or more
> * contributor license agreements. See the NOTICE file distributed with
> * this work for additional information regarding copyright ownership.
> * The ASF licenses this file to You under the Apache License, Version 2.0
> * (the "License"); you may not use this file except in compliance with
> * the License. You may obtain a copy of the License at
> *
> * http://www.apache.org/licenses/LICENSE-2.0
> *
> * Unless required by applicable law or agreed to in writing, software
> * distributed under the License is distributed on an "AS IS" BASIS,
> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> * See the License for the specific language governing permissions and
> * limitations under the License.
> */
> package org.apache.wicket.util.collections;
>
>
> import java.io.IOException;
> import java.util.HashMap;
> import java.util.concurrent.ConcurrentHashMap;
>
> import org.apache.wicket.Page;
> import org.apache.wicket.util.io.ByteArrayOutputStream;
> import org.apache.wicket.util.io.WicketObjectOutputStream;
> import org.apache.wicket.util.tester.WicketTester;
>
> public class Tester
> {
> private static final int NUMBER_OF_PAGES = 1;
>
>
> public static void main(String[] args) throws Exception
> {
> int intHashMapSize = writeMap(populatedIntHashMap());
> int hashMapSize = writeMap(populatedHashMap());
> int concurrentHashMapSize =
> writeMap(populatedConcurrentHashMap());
> double hashMapIsLargerPercetange =
> ((Double.valueOf(hashMapSize) / intHashMapSize) - 1) * 100;
> double concurrentHashMapIsLargerPercetange =
> ((Double.valueOf(concurrentHashMapSize) / intHashMapSize) - 1) * 100;
> System.out.printf("HashMap is %.3f%% larger than
> IntHashMap.%n", hashMapIsLargerPercetange);
> System.out.printf("ConcurrentHashMap is %.3f%% larger than
> IntHashMap.%n",
> concurrentHashMapIsLargerPercetange);
> }
>
> private static int writeMap(Object map) throws IOException
> {
> ByteArrayOutputStream out = new ByteArrayOutputStream();
> WicketObjectOutputStream objectOutputStream = new
> WicketObjectOutputStream(out);
> objectOutputStream.writeObject(map);
> System.out.printf("map implementation: %s -- size of
> outputstream: %d bytes.%n",
> map.getClass().getName(), out.size());
> return out.size();
> }
>
> private static HashMap<Integer, Page> populatedHashMap()
> {
> new WicketTester();
> HashMap<Integer, Page> map = new HashMap<Integer, Page>();
> for (int i = 0; i < NUMBER_OF_PAGES; i++)
> {
> map.put(i, createPage());
> }
> return map;
> }
>
> private static ConcurrentHashMap<Integer, Page>
> populatedConcurrentHashMap()
> {
> new WicketTester();
> ConcurrentHashMap<Integer, Page> map = new
> ConcurrentHashMap<Integer, Page>();
> for (int i = 0; i < NUMBER_OF_PAGES; i++)
> {
> map.put(i, createPage());
> }
> return map;
> }
>
>
> private static IntHashMap<Page> populatedIntHashMap()
> {
> new WicketTester();
> IntHashMap<Page> map = new IntHashMap<Page>();
> for (int i = 0; i < NUMBER_OF_PAGES; i++)
> {
> map.put(i, createPage());
> }
> return map;
> }
>
>
> private static Page createPage()
> {
> Page page = new Page()
> {
> };
> page.detach();
> return page;
>
> }
> }
>
>
> Igor Vaynberg wrote:
>
>> exactly what the javadoc says, its a map that does not need to store a
>> key object. so it is smaller than a regular hashmap when serialized or
>> kept in memory.
>>
>> -igor
>>
>> On Thu, Feb 12, 2009 at 1:40 PM, Tuomas Kärkkäinen
>> <[email protected]> wrote:
>>
>>> Hi,
>>>
>>> I was looking at IntHashMap in wicket trunk.
>>>
>>> I couldn't figure out what it does.
>>>
>>> The implementation of hashcode for Integer is value, and the autoboxing
>>> of
>>> int to Integer comes out to Integer.valueOf(int) which is implemented as
>>> an
>>> array lookup for Integers in the range of -128 to 127, and beyond that
>>> it's
>>> just new Integer(int). Page ids start at zero for each page in each
>>> session
>>> so most of the time they will be between zero and 127.
>>>
>>> Br,
>>> Tuomas
>>>
>>>
>>>
>