HashMap implementations and Integer specializations

charlie hunt charlie.hunt at sun.com
Mon Jun 9 22:38:56 UTC 2008


Martin,

I'll accept your adding of the comment as a solution to my suggested 
improvement.

charlie ...

P.S.  I sense you did not like my feedback / comments, or were somehow 
offended. I was trying to offer you a suggestion to improve to your test 
case.

Martin Buchholz wrote:
> Charlie,
>
> Test case code is different from regular code
> in that bad practice is often a good idea.
> People should know better than to "fix" test cases
> using their IDE.
>
> But I added this comment:
>
>         // This code intentionally uses the denigrated constructors
>         // that are guaranteed to return a unique object!
>
> Martin
>
> On Mon, Jun 9, 2008 at 11:26 AM, charlie hunt <charlie.hunt at sun.com> wrote:
>   
>> Martin,
>>
>> I'm rather shocked at your response!
>>
>> Consider for example, there's a very popular tool out their that integrates
>> very well into NetBeans  IDE and Eclipse IDE which suggests changing all
>> 'new Integer(), new Long()' calls into 'Integer.valueOf() & Long.valueOf()'.
>>  Take a quick look at how new Integer() contrasts with Integer.valueOf().
>>
>> Suppose in the future as Martin moves on to bigger and better things beyond
>> OpenJDK and a future maintainer looks at your test case and updates it to
>> use Integer.valueOf() and Long.valueOf() as result of such a tool mentioned
>> above.   Should that happen, I don't think your test case would test what it
>> was intended to test.
>>
>> Would not your test case be improved by choosing values well outside the
>> values contained in the IntegerCache & LongCache?
>>
>> charlie ...
>>
>> Martin Buchholz wrote:
>>     
>>> Charlie,
>>>
>>> Hotspot engineers throughout the ages
>>> have been tempted to optimize away
>>> object identity semantics of Integer and String,
>>> but I'm pretty sure that for e.g. new Integer(x)
>>> and new String(y) hotspot will certainly continue
>>> to return _new_ objects (unless of course
>>> the application can be proven to not tell the
>>> difference), and there are sufficient
>>> regression tests to keep all of us in line.
>>>
>>> Martin
>>>
>>> On Mon, Jun 9, 2008 at 7:57 AM, charlie hunt <charlie.hunt at sun.com> wrote:
>>>
>>>       
>>>> wrt the Integer & Long values you use in your test case ...
>>>>
>>>> You might consider using larger Integer & Long values, ones that lie
>>>> outside
>>>> the range of Integer.IntegerCache & Long.LongCache to avoid any potential
>>>> confusion about whether the values you are putting into the Map might get
>>>> grabbed from the IntegerCache or LongCache via some "magic" of the
>>>> HotSpot
>>>> compiler, i.e it's conceivable a call to 'new Integer()' could be
>>>> transformed into Integer.valueOf()'.
>>>>
>>>> charlie ...
>>>>
>>>> Martin Buchholz wrote:
>>>>
>>>>         
>>>>> JavaOne 2008 technical session PDFs are now available
>>>>>
>>>>>
>>>>>
>>>>> http://developers.sun.com/learning/javaoneonline/j1online.jsp?track=javase&yr=2008
>>>>>
>>>>> I was surprised to discover a discussion of
>>>>> HashMap optimization at the JavaOne talk
>>>>> http://developers.sun.com/learning/javaoneonline/2008/pdf/TS-6434.pdf
>>>>>
>>>>> Did I miss an announcement of that?
>>>>>
>>>>> A comment on that talk:
>>>>>
>>>>> It is easy to make the mistake of thinking that HashMap does not
>>>>> have to store the actual Integer key in the call to put.
>>>>> Unfortunately, Java's evil semantics (everything is an Object,
>>>>> everything is a Lock, everything has an Identity) require
>>>>> that the exact same objects inserted into a HashMap can be
>>>>> removed later.  This means that specialized submaps will have
>>>>> a harder time optimizing for footprint.  (I do think the
>>>>> algorithm presented in the talk is correct, since the front cache
>>>>> is likely only used for get(), and not, e.g. for entrySet().iterator())
>>>>>
>>>>> I intend to check in a test case modification that will ensure
>>>>> that future optimizations do not violate the current compatibility
>>>>> guarantees.
>>>>>
>>>>> diff --git a/test/java/util/Collection/MOAT.java
>>>>> b/test/java/util/Collection/MOAT.java
>>>>> --- a/test/java/util/Collection/MOAT.java
>>>>> +++ b/test/java/util/Collection/MOAT.java
>>>>> @@ -544,6 +544,27 @@ public class MOAT {
>>>>>        check(m.size() != 0 ^ m.isEmpty());
>>>>>    }
>>>>>
>>>>> +    private static void testPutPreversesObjectIdentity(Map<?,?> m,
>>>>> +                                                       Object key,
>>>>> +                                                       Object val) {
>>>>> +        try {
>>>>> +            Map<Object,Object> m2 = m.getClass().newInstance();
>>>>> +            m2.put(key, val);
>>>>> +            Map.Entry<Object,Object> e =
>>>>> m2.entrySet().iterator().next();
>>>>> +            check(e.getKey()   == key);
>>>>> +            check(e.getValue() == val);
>>>>> +            check(m2.keySet().iterator().next() == key);
>>>>> +            check(m2.values().iterator().next() == val);
>>>>> +        } catch (Throwable t) { unexpected(t); }
>>>>> +    }
>>>>> +
>>>>> +    private static void testPutPreversesObjectIdentity(Map<?,?> m) {
>>>>> +        testPutPreversesObjectIdentity(m, new Integer(42),  new
>>>>> Integer(43));
>>>>> +        testPutPreversesObjectIdentity(m, new Long(42L),    new
>>>>> Long(43L));
>>>>> +        testPutPreversesObjectIdentity(m, new Double(42.0), new
>>>>> Double(43.0));
>>>>> +        testPutPreversesObjectIdentity(m, new String("42"), new
>>>>> String("43"));
>>>>> +    }
>>>>> +
>>>>>    private static void testMap(Map<Integer,Integer> m) {
>>>>>        System.out.println("\n==> " + m.getClass().getName());
>>>>>
>>>>> @@ -572,6 +593,7 @@ public class MOAT {
>>>>>        }
>>>>>
>>>>>        if (supportsPut(m)) {
>>>>> +            testPutPreversesObjectIdentity(m);
>>>>>            try {
>>>>>                check(m.put(3333, 77777) == null);
>>>>>                check(m.put(9134, 74982) == null);
>>>>>
>>>>>
>>>>>           
>>>> --
>>>>
>>>> Charlie Hunt
>>>> Java Performance Engineer
>>>>
>>>> <http://java.sun.com/docs/performance/>
>>>>
>>>>
>>>>
>>>>         
>> --
>>
>> Charlie Hunt
>> Java Performance Engineer
>>
>> <http://java.sun.com/docs/performance/>
>>
>>
>>     

-- 

Charlie Hunt
Java Performance Engineer

<http://java.sun.com/docs/performance/>




More information about the core-libs-dev mailing list