You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by bu...@apache.org on 2001/03/10 04:54:19 UTC

[Bug 924] New - The equals method of StringKey.java is not symmetric.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=924

*** shadow/924	Fri Mar  9 19:54:19 2001
--- shadow/924.tmp.12024	Fri Mar  9 19:54:19 2001
***************
*** 0 ****
--- 1,158 ----
+ +============================================================================+
+ | The equals method of StringKey.java is not symmetric.                      |
+ +----------------------------------------------------------------------------+
+ |        Bug #: 924                         Product: XalanJ2                 |
+ |       Status: NEW                         Version: 2.0.0                   |
+ |   Resolution:                            Platform: PC                      |
+ |     Severity: Normal                   OS/Version:                         |
+ |     Priority:                           Component: Xalan                   |
+ +----------------------------------------------------------------------------+
+ |  Assigned To: xalan-dev@xml.apache.org                                     |
+ |  Reported By: scott_boag@lotus.com                                         |
+ |      CC list: Cc:                                                          |
+ +----------------------------------------------------------------------------+
+ |          URL:                                                              |
+ +============================================================================+
+ |                              DESCRIPTION                                   |
+ In message "Re: The equals method of StringKey.java is not symmetric."
+     on 01/01/29, Scott_Boag@lotus.com <Sc...@lotus.com> writes:
+ 
+ > Hmm... perhaps not, since the equals method of String does an instanceof
+ > before casting to a string.  I'm not sure how to solve this.  Any
+ > suggestions?  I think using a string key to cache the hash value is a
+ > well-known optimization technique.
+ 
+ java.lang.String of JDK 1.3 caches the hash code of the string.
+ So, when used with JDK 1.3,  the optimization technique used
+ for StringKey will lose its significance.  It may even have
+ a negative effect.
+ 
+ How about giving up using StringKey?
+ 
+ Following is my test program which shows that using
+ simple strings for Hashtable keys is more efficient
+ than using StringKeys.
+ 
+ Program:
+ 
+ import java.util.Random;
+ import java.util.Hashtable;
+ 
+ public class StringKeyTest {
+ 
+     private String[] keys;
+ 
+     /* main */
+     public static void main (String args[]) {
+ 
+         try {
+             StringKeyTest t = new StringKeyTest();
+ 		     if (args[0].equals("String")) {
+ 		 		 t.testString();
+ 		     }
+ 		     else if (args[0].equals("StringKey")) {
+ 		 		 t.testStringKey();
+ 		     }
+         } catch (Exception e) {
+             e.printStackTrace();
+         }
+     }
+     
+     public StringKeyTest () {
+ 		     keys = new String[100000];
+ 		     Random r = new Random(237485087L);
+ 		     for(int i = keys.length-1; i >= 0; i--) {
+ 		 		 keys[i] = Integer.toString(r.nextInt())+"ABCD" 
+ + Integer.toString(i);
+ 		     }
+     }
+ 
+     private void testString() {
+ 		     Hashtable h = new Hashtable();
+ 		     long s;
+ 		     System.out.println("Hashtable using simple String");
+ 		     s = System.currentTimeMillis();
+ 		     for(int i = keys.length-1; i >= 0; i--) {
+ 		 		 h.put(keys[i], keys[i]);
+ 		     }
+ 		     s = System.currentTimeMillis() - s;
+ 		     System.out.print("put: ");
+             System.out.println(s);
+ 		     s = System.currentTimeMillis();
+ 		     for(int i = keys.length-1; i >= 0; i--) {
+ 		     		 h.get(keys[i]);
+ 		     }
+ 		     s = System.currentTimeMillis() - s;
+ 		     System.out.print("get: ");
+ 		     System.out.println(s);    
+     }
+ 
+     private void testStringKey() {
+ 		     Hashtable h = new Hashtable();
+ 		     long s;
+ 		     System.out.println("Hashtable using StringKey");
+ 		     s = System.currentTimeMillis();
+ 		     for(int i = keys.length-1; i >= 0; i--) {
+ 		 		 h.put((new StringKey(keys[i])), keys[i]);
+ 		     }
+ 		     s = System.currentTimeMillis() - s;
+ 		     System.out.print("put: ");
+ 		     System.out.println(s);    
+ 		     s = System.currentTimeMillis();
+ 		     for(int i = keys.length - 1; i >= 0; i--) {
+ 		     		 h.get(new StringKey(keys[i]));
+ 		     }
+ 		     s = System.currentTimeMillis() - s;
+ 		     System.out.print("get: ");
+ 		     System.out.println(s);
+ 		     s = System.currentTimeMillis();
+ 		     for(int i = keys.length - 1; i >= 0; i--) {
+ 		     		 h.get(keys[i]);
+ 		     }
+ 		     s = System.currentTimeMillis() - s;
+ 		     System.out.print("get*: ");
+ 		     System.out.println(s);
+     }
+ 
+ // copied from org.apache.xalan.xpath.xml.StringKey
+ private class StringKey extends Object
+ {
+   private String m_str;
+   int m_hash;
+     
+   public StringKey(String key)
+   {
+     m_str = key;
+     m_hash = key.hashCode();
+   }
+   
+   public int hashCode()
+   {
+     return m_hash;
+   }
+   
+   public final boolean equals(Object obj)
+   {
+     return obj.equals(m_str);
+   }
+ }
+ 
+ }
+ 
+ 
+ Results:
+ 
+ bash$ java -version
+ java version "1.3.0"
+ Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
+ Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)
+ bash$ CLASSPATH=. java StringKeyTest String
+ Hashtable using simple String
+ put: 1150
+ get: 220
+ bash$ CLASSPATH=. java StringKeyTest StringKey
+ Hashtable using StringKey
+ put: 3080
+ get: 500
+ get*: 270
+ bash$