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 <[EMAIL PROTECTED]> 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/>