Discussing this nitpicking has taken time away from fixing bugs,
improving things that really matter, running wicket in a profiler, or
even helping out on the mailinglist. It serves nothing other than
bellybutton gazing. Instead of thinking about how to implement multi
window support we have to defend the existence of a class that is
useful to us?

This class has its purpose, it is used inside wicket. It has a goal:
minimize memory usage. It serves its goal. Is it a maintenance
nightmare? no. Does it increase Wicket's conceptual surface? No. Did I
know it existed before you brought it up? No. Do I need it in my
day-to-day Wicket coding? No. Does it get in the way in my day-to-day
Wicket coding? No. Does it increase my time spent on supporting
Wicket? No, unless someone starts complaining that it exists.

Martijn

On Fri, Feb 13, 2009 at 10:15 PM, Tuomas Kärkkäinen
<[email protected]> wrote:
> Igor,
>
> Wicket is the best way to develop web applications and I appreciate every
> day the wonderful work you, Johan and others are doing. But, I would love to
> see Wicket focus on the essentials of web development.  This would make it
> easier to reason about the functioning of Wicket, and it would make it
> easier to contribute bug fixes, improvements, patches etc.
>
> If the purpose of IntHashMap is to provide the functionality of:
>
> public class IntHashMap<V> extends HashMap<Integer,V>  {
>  V put(int i, V value) {
>    return super.put(Integer.valueOf(i),value);
>  }
>
>  V get(int i) {
>    super.get(Integer.valueOf(i));
>  }
> }
>
> then Wicket can do the same as it did earlier but with 1000 less lines of
> code.
> Perhaps those 1000 lines could be used on some other amazing feature.
>
> Br,
> Tuomas
>
> Quoting Igor Vaynberg <[email protected]>:
>
>> this is borderline nitpicking. just because it is coded the way you
>> wouldnt doesnt mean we have to change it.
>>
>> -igor
>>
>> On Fri, Feb 13, 2009 at 12:23 PM, Antony Stubbs  <[email protected]>
>> wrote:
>>>
>>> Are we also not allowed to debate the merits of existing functionality?
>>>
>>> On 13/02/2009, at 7:46 PM, Igor Vaynberg wrote:
>>>
>>>> why are we even talking about it. nothing is broken in wicket,
>>>> correct? you are not forced to use it in your code. we like it. it
>>>> does not impact you. where is the problem?
>>>>
>>>> -igor
>>>>
>>>> On Fri, Feb 13, 2009 at 11:32 AM, Johan Compagner <[email protected]>
>>>> wrote:
>>>>>
>>>>> you are forgetting that the value that is stored is also in mem
>>>>> So if the value is an Integer object that is again an 4 bytes ci, 4
>>>>> bytes
>>>>> oi
>>>>> and 4 bytes value
>>>>>
>>>>> But the IntHashmap is far from complex, i even like it if i just have
>>>>> int
>>>>> ->
>>>>> value (which is where it is used for)
>>>>> else i have to wrap those ints in a Integer object first (or auto box
>>>>> it
>>>>> which i dont like to much)
>>>>>
>>>>> so it is a big quicker, its smaller in mem size, and is easier to use
>>>>> when
>>>>> you just have int keys.. i dont see any drawback
>>>>>
>>>>> johan
>>>>>
>>>>>
>>>>> On Fri, Feb 13, 2009 at 19:42, Tuomas Kärkkäinen
>>>>> <[email protected]>wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> The int in Entry is a 32bit value so it takes 4 bytes of memory.
>>>>>>
>>>>>> In a 32bit JVM, a reference, ie. a pointer takes 4 bytes.  In a 64bit
>>>>>> JVM
>>>>>> it takes 8 bytes.
>>>>>>
>>>>>> HashMap's Entry consumes on a 32bit jvm:
>>>>>> 4 bytes for the class identifier,
>>>>>> 4 bytes for the object identifier,
>>>>>> 4 bytes for the key
>>>>>> 4 bytes for the value
>>>>>> 4 bytes for the hash
>>>>>> 4 bytes for next
>>>>>>
>>>>>> a total of 24 bytes.
>>>>>>
>>>>>> and on a 64bit jvm
>>>>>> 4 bytes for the class identifier,
>>>>>> 4 bytes for the object identifier,
>>>>>> 8 bytes for the key
>>>>>> 8 bytes for the value
>>>>>> 4 bytes for the hash
>>>>>> 8 bytes for next
>>>>>>
>>>>>> 36 bytes.
>>>>>>
>>>>>> IntHashMap's entry takes:
>>>>>> 4 bytes for the class identifier,
>>>>>> 4 bytes for the object identifier,
>>>>>> 4 bytes for key
>>>>>> 4 bytes for value
>>>>>> 4 bytes for next
>>>>>> 20 total on 32bits
>>>>>> or
>>>>>> 4 bytes for the class identifier,
>>>>>> 4 bytes for the object identifier,
>>>>>> 4 bytes for key
>>>>>> 8 bytes for value
>>>>>> 8 bytes for next
>>>>>> 28 total on 64bits
>>>>>>
>>>>>> java.util.AbstractMap$SimpleEntry<K,V> and consequently
>>>>>> java.util.concurrent.ConcurrentHashMap$WriteThroughEntry
>>>>>> only has serialVersionUID, key and value.
>>>>>> which is 24 bytes on 32bit and 32bytes on 64bit.
>>>>>>
>>>>>> As an aside, on my core2, the 32-bit hotspot seems to align objects on
>>>>>> 8byte boundaries, so 20 and 24 bytes both consume 24 bytes.
>>>>>>
>>>>>> My personal conclusion would be that if there is a memory saving
>>>>>> advantage
>>>>>> to using IntHashMap, it is negligible.  Further, the accidental
>>>>>> complexity
>>>>>> IntHashMap introduces outweighs the memory savings.
>>>>>>
>>>>>> Br,
>>>>>> Tuomas
>>>>>>
>>>>>> Quoting Johan Compagner <[email protected]>:
>>>>>>
>>>>>> 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
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>
>>>
>>
>
>
>



-- 
Become a Wicket expert, learn from the best: http://wicketinaction.com
Apache Wicket 1.3.5 is released
Get it now: http://www.apache.org/dyn/closer.cgi/wicket/1.3.

Reply via email to