This is the mail archive of the java@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: gcj's IO performance vs blackdown JDK


On Dec 24, 2003, at 3:36 PM, Mohan Embar wrote:

Thanks Christopher, this is a useful test case. I suspect the problem
here is our horribly inefficient implementation of
BufferedReader.readLine(). Given that it is calling a synchronized
read() method in a loop for every character in the stream, I'm
surprised its only 3x slower! You might like to have a go at making a
more efficient implementation, or alternatively, file an "RFE" bug in
bugzilla.

This has gone unclaimed for awhile, so I started messing around with it.


Actually, the problem isn't with the read() method. Although the call
to it is synchronized, it gets called once and then the entire filled
contents of the buffer are used.

In the code below, I got rid of the synchronization, but the major gain
came from reusing the StringBuffer throughout the lifetime of the BufferedReader
instance. This got me from 33s to 23s on my P450/256M. (The JRE time is 15s.)
I'm able to get an additional 2s gain (10%) by implementing lineEnd() in CNI,
thereby presumably avoiding the bounds checking.

Interesting. I actually already rewrote much of BufferedReader (based partly on the BufferedInputStream code) and got a small speed improvement (along with a big reduction in complexity), before realizing that the real performance problem was in InputStreamReader where the character conversion occurs. What was happening is that InputStreamReader was converting characters into a small internal buffer (only 100 chars IIRC), so when BufferedReader called read() on the InputStreamReader it only got a fraction of the amount of data needed to fill up its buffer. This also meant that there was an extra unnecessary layer of copying going on. Solution: fix InputSreamReader to decode characters directly into the array given to it in the read() method. This brought us up to about equal or slightly faster than the JRE 1.4.2 on Chris's test.


From memory, my readLine() implementation only creates a StringBuffer in the event that the line crosses a boundary between buffers (ie the StringBuffer is used to store the start of a line when the buffer needs to be refilled), so given a full 8192 char buffer, the need to create a StringBuffer should be rare at least for input with "normal" sized lines.

I didn't get around to submitting this yet due partly to lack of time and partly because, being a significant code change and not fixing a bug, it isn't really suitable to commit before 3.4 branches. Unfortunately I don't have access to my development machine right now and I didn't think to grab a copy of my tree on my laptop, otherwise I'd post a copy. I'll post it next week.

Regards

Bryce.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]