I wondered how much chaining there has to be before performance
gets really bad when I checked your program more closely. Your example program would produce external chains of length:
2000000/20011 ~ 100.
I can see performance slow down well before 100.000 unique string are interned.
And remember that the number of strings that FOP explicit intern must be added to the number of intern'ed string that the classloaders has created and whatever all the other components that are loaded has created.
Ad.2: The memory sharing can implemented by using intern'ed string but it is a very bad idea to do that. A normal java.util.Hashtable can be used just as well for the implementation of memory sharing:
HashMap you mean.
Well sure, but a Hashtable is slightly faster.
I've attached another demo program that shows that intern'ing is slower than doing memory sharing with a Hashtable. This programs creates 13520 unique strings and does 9 subsequent lookup of the same strings.
regards, finn
import java.util.Hashtable; public class interntst2 { public static void main(String[] args) throws Exception { interntst2 test = new interntst2(); test.testIntern(); test.testShared();
long now; System.gc(); now = System.currentTimeMillis(); test.testIntern(); System.out.println("testIntern:" + (System.currentTimeMillis() - now)); System.gc(); now = System.currentTimeMillis(); test.testShared(); System.out.println("testShared:" + (System.currentTimeMillis() - now)); } public void testIntern() { int cnt = 135200; String[] arr = new String[cnt]; long now = System.currentTimeMillis(); for (int i = 0; i < cnt; i++) { String s = ("attribute" + (i % 13520)).intern(); arr[i] = s; } } public void testShared() { int cnt = 135200; String[] arr = new String[cnt]; long now = System.currentTimeMillis(); for (int i = 0; i < cnt; i++) { String s = getSharedValue("attribute" + (i % 13520)); arr[i] = s; } } Hashtable hashTable = new Hashtable(); public String getSharedValue(String value) { String ret = (String) hashTable.get(value); if (ret != null) return ret; hashTable.put(value, value); return value; } }