I executed your test on windows XP. And the result is: output of RI: time: 0 time: 0
output of harmony: time: 0 time: 0 Seems the performance problem only occurs on RH linux platform. At this point, my guess is native I/O of archive module on RH Linux may cause the slowdown. I checked JIRA 4950. It would be better to specify the environment information for this JIRA. 2007/10/16, Regis <[EMAIL PROTECTED]>: > > > Spark Shen wrote: > > Hi > > I read your comments in > http://issues.apache.org/jira/browse/HARMONY-4942. > > And I agree with you different apps context uses different classloader > for > > loading different > > properties as you said. > > > > I did not catch you is 'I'm not sure how ri do this'. > just want to clarify behavior of ri > > I just want to clarify my understanding here: > > You are not quite sure about how RI handle modification to the same > > jndi.properties file > > in different classloaders. And in your post here, you proved that, > indeed > > different classloaders in RI will > > overwrite each other. > > > > And I think we'd better follow RI, since many application servers are > > already running stably on it. > agree > > 2007/10/16, Regis <[EMAIL PROTECTED]>: > >> Hi, > >> I survey the issue Harmony-4942, found the Harmony's behavior of > finding > >> "jndi.properties" file is not the same as ri's: > >> Harmony re-search the whole CLASSPATH every construction time, while ri > >> just search once when using a classloader to > >> find the file at first time. The following code prove it: > >> > >> =============begin============= > >> > >> URL url = new File("test1").toURL(); > >> URLClassLoader cltest1 = new URLClassLoader(new URL[] { > url > >> }, > >> Thread.currentThread().getContextClassLoader()); > >> Thread test1 = new Thread(new Runnable() { > >> > >> public void run() { > >> try { > >> System.out.println("test1 classloader" > >> + Thread.currentThread() > >> .getContextClassLoader()); > >> FileOutputStream fos = new FileOutputStream( > >> "test1/jndi.properties"); > >> PrintStream ps = new PrintStream(fos); > >> ps > >> > >> .println(" > >> java.naming.factory.initial=regis.jndi.MyDefaultInitialContextFactory > "); > >> > >> ps.println("java.naming.provider.url=http://test1"); > >> ps.close(); > >> > >> InitialContext context = new InitialContext(); > >> System.out.println("test1.context= " + > >> context); > >> System.out.println("test1.context.env=" > >> + context.getEnvironment()); > >> > >> File file = new File("test1/jndi.properties"); > >> file.delete(); > >> > >> // create new properties file with different > >> values > >> fos = new FileOutputStream( > >> "test1/jndi.properties"); > >> ps = new PrintStream(fos); > >> ps > >> > >> .println(" > >> java.naming.factory.initial=regis.jndi.MyDefaultInitialContextFactory > "); > >> > >> ps.println("java.naming.provider.url=http://test1.new"); > >> ps.close(); > >> > >> context = new InitialContext(); > >> System.out.println("test1.new.context=" + > >> context); > >> System.out.println("test1.new.context.env=" > >> + context.getEnvironment()); > >> > >> } catch (Exception e) { > >> e.printStackTrace(); > >> } > >> } > >> > >> }); > >> // use different classloader > >> test1.setContextClassLoader(cltest1); > >> > >> test1.start(); > >> > >> url = new File("test2").toURL(); > >> URLClassLoader clSrc = new URLClassLoader(new URL[] { url > >> }, Thread > >> .currentThread().getContextClassLoader()); > >> > >> Thread test2 = new Thread(new Runnable() { > >> > >> public void run() { > >> try { > >> System.out.println("test2 classloader" > >> + Thread.currentThread() > >> .getContextClassLoader()); > >> FileOutputStream fos = new FileOutputStream( > >> "test2/jndi.properties"); > >> PrintStream ps = new PrintStream(fos); > >> ps > >> > >> .println(" > >> java.naming.factory.initial=regis.jndi.MyDefaultInitialContextFactory > "); > >> > >> ps.println("java.naming.provider.url=http://test2"); > >> ps.close(); > >> InitialContext context = new InitialContext(); > >> System.out.println("test2.context= " + > >> context); > >> System.out.println("test2.context.env=" > >> + context.getEnvironment()); > >> } catch (Exception e) { > >> e.printStackTrace(); > >> } > >> } > >> > >> }); > >> > >> // use different classloader > >> test2.setContextClassLoader(clSrc); > >> test2.start(); > >> > >> ===================end================= > >> (I slightly modify MyDefaultInitialContextFactory, add environment > >> values to MyInitialContext after initial) > >> > >> the output is below, using jre1.6.0: > >> > >> ============start output=============== > >> > >> test1 [EMAIL PROTECTED] > >> test1.context= [EMAIL PROTECTED] > >> > >> > test1.context.env={java.naming.factory.initial=regis.jndi.MyDefaultInitialContextFactory > >> , > >> java.naming.provider.url=http://test1} > >> [EMAIL PROTECTED] > >> > >> > test1.new.context.env={java.naming.factory.initial=regis.jndi.MyDefaultInitialContextFactory > >> , > >> java.naming.provider.url=http://test1} > >> test2 [EMAIL PROTECTED] > >> test2.context= [EMAIL PROTECTED] > >> > >> > test2.context.env={java.naming.factory.initial=regis.jndi.MyDefaultInitialContextFactory > >> , > >> java.naming.provider.url=http://test2} > >> > >> =============end output================= > >> > >> So under same classloader, ri just search property file once. > >> > >> In harmony we can use a map to hold property values for each > classloader > >> to avoid search at every construction time. > >> But i found Harmony is still slower than ri at first time to constuct > >> InitialContext object, the most time is consumed at > >> org.apache.harmony.jndi.internal.EnvironmentReader line 233: > >> p.load(is); > > > > > > As for the performance issue in Properties.java, I think may be it's > caused > > by lack of cache. I am interested, and will look into the issue. > > BTW, did you report a seperate JIRA for it? > the jira is here: https://issues.apache.org/jira/browse/HARMONY-4950 > > > > Then i write some sample code to test performance of Properties.load(): > >> Properties pro = new Properties(); > >> URL url = new > >> > >> > >> > URL("jar:file:/home/bahamut/harmony/trunk/deploy/jdk/jre/lib/boot/jndi.jar!/jndi.properties"); > >> InputStream in = url.openStream(); > >> long start = System.currentTimeMillis(); > >> pro.load(in); > >> long end = System.currentTimeMillis(); > >> System.out.println("time: " + (end - start)); > >> in.close(); > >> > >> pro = new Properties(); > >> url = new > >> > >> > >> > URL("jar:file:/home/bahamut/harmony/trunk/deploy/jdk/jre/lib/boot/jndi.jar!/jndi.properties"); > >> in = url.openStream(); > >> start = System.currentTimeMillis(); > >> pro.load(in); > >> end = System.currentTimeMillis(); > >> System.out.println("time: " + (end - start)); > >> in.close(); > >> > >> output of ri: > >> time: 1 > >> time: 0 > >> > >> output of harmony: > >> time: 231 > >> time: 1 > >> > >> Harmony is slower than ri *two hundred* times!! > >> in above test, property file is in jndi.jar about 230k, if not in jar > >> file, the time of harmony and ri are very close, > >> so i think there must be some problems of archive module. Is it because > >> of we using different algorithm with ri, > >> or our implementation has bugs? > >> > >> Best Regards, > >> Regis. > >> > > > > > > > > Best Regards, > Regis. > -- Spark Shen China Software Development Lab, IBM
