This is the mail archive of the java-patches@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]

[PATCH] for Review: BufferedReader and InputStreamReader Optimizations (Updated)


Hi People,

Knock knock. It's me again, with the >50% improvement for
BufferedReader.readline():

BEFORE:
running gcj version
100000

real    0m35.892s
user    0m33.416s
sys     0m1.400s
running jdk version
100000

real    0m17.067s
user    0m15.590s
sys     0m1.088s

AFTER:
running gcj version
100000

real    0m19.490s
user    0m16.068s
sys     0m1.316s
running jdk version
100000

real    0m17.285s
user    0m15.676s
sys     0m1.125s

(
The above test is here:

http://gcc.gnu.org/ml/java/2003-12/msg00021.html
)

Bryce and I spoke off-list about my original submission:

http://gcc.gnu.org/ml/java-patches/2004-q1/msg00008.html

...and he pointed out that it might be controversial to
introduce a native method for BufferedReader purely for
a small speed improvement. Although removing this makes
Sun's JRE win over gcj, I'm willing to live with this
compromise and I removed the native method from this
updated patch, which is against the trunk.

Bryce said off-list that we should consider a combination
of his efforts:

http://gcc.gnu.org/ml/java/2004-01/msg00029.html

...and mine. I would love for this to happen, but given
that there were possible issues with Bryce's initial attempt:

http://gcc.gnu.org/ml/java/2004-01/msg00035.html

...my recommendation would be to check my version in,
enjoy the immediate performance gain, then let Bryce, Dalibor
or whoever else tear this to pieces if he is so inclined.

-- Mohan
http://www.thisiscool.com/
http://www.animalsong.org/

ChangeLog
2004-01-29  Mohan Embar  <gnustuff@thisiscool.com>

	* java/io/BufferedReader.java (sbuf): New field.
	(readLine): Use String.valueOf instead of new String() as per
	Per Bothner's suggestion. Use instance sbuf field instead of a
	local StringBuffer instance.
	* java/io/InputStreamReader.java (read(char[],int,int)): Pass the
	caller's buffer to refill().
	(read(void)): Pass our internal work buffer to refill if our
	input queue is empty.
	(refill): Changed return type to int. Use the specified buffer
	instead of our work buffer as per Bryce McKinlay's suggestion.
	Return the number of characters read or -1 for EOF.

Index: java/io/BufferedReader.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/io/BufferedReader.java,v
retrieving revision 1.16
diff -u -2 -r1.16 BufferedReader.java
--- java/io/BufferedReader.java	28 Dec 2003 11:54:17 -0000	1.16
+++ java/io/BufferedReader.java	30 Jan 2004 03:36:35 -0000
@@ -90,4 +90,9 @@
 
   /**
+   * The line buffer for <code>readLine</code>.
+   */
+  private StringBuffer sbuf = null;
+
+  /**
     * Create a new <code>BufferedReader</code> that will read from the 
     * specified subordinate stream with a default buffer size of 8192 chars.
@@ -440,5 +445,5 @@
     if (i < limit)
       {
-	String str = new String(buffer, pos, i - pos);
+	String str = String.valueOf(buffer, pos, i - pos);
 	pos = i + 1;
 	// If the last char in the buffer is a '\r', we must remember
@@ -451,5 +456,8 @@
 	return str;
       }
-    StringBuffer sbuf = new StringBuffer(200);
+    if (sbuf == null)
+      sbuf = new StringBuffer(200);
+    else
+      sbuf.setLength(0);
     sbuf.append(buffer, pos, i - pos);
     pos = i;
Index: java/io/InputStreamReader.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/io/InputStreamReader.java,v
retrieving revision 1.15
diff -u -2 -r1.15 InputStreamReader.java
--- java/io/InputStreamReader.java	9 May 2003 07:10:58 -0000	1.15
+++ java/io/InputStreamReader.java	30 Jan 2004 03:36:35 -0000
@@ -232,8 +232,6 @@
 	if (wavail <= 0)
 	  {
-	    // Nothing waiting, so refill our buffer.
-	    if (! refill ())
-	      return -1;
-	    wavail = wcount - wpos;
+	    // Nothing waiting, so refill their buffer.
+	    return refill(buf, offset, length);
 	  }
 
@@ -263,7 +261,12 @@
 	if (wavail <= 0)
 	  {
-	    // Nothing waiting, so refill our buffer.
-	    if (! refill ())
+	    // Nothing waiting, so refill our internal buffer.
+	    wpos = wcount = 0;
+	    if (work == null)
+	       work = new char[100];
+	    int count = refill(work, 0, work.length);
+	    if (count == -1)
 	      return -1;
+	    wcount += count;
 	  }
 
@@ -272,13 +275,8 @@
   }
 
-  // Read more bytes and convert them into the WORK buffer.
-  // Return false on EOF.
-  private boolean refill () throws IOException
+  // Read more bytes and convert them into the specified buffer.
+  // Returns the number of converted characters or -1 on EOF.
+  private int refill(char[] buf, int offset, int length) throws IOException
   {
-    wcount = wpos = 0;
-
-    if (work == null)
-      work = new char[100];
-
     for (;;)
       {
@@ -291,16 +289,12 @@
 	in.reset ();
 	if (! r)
-	  return false;
+	  return -1;
 	converter.setInput(in.buf, in.pos, in.count);
-	int count = converter.read (work, wpos, work.length - wpos);
+	int count = converter.read(buf, offset, length);
 	in.skip(converter.inpos - in.pos);
 	if (count > 0)
-	  {
-	    wcount += count;
-	    return true;
-	  }
+	  return count;
       }
   }
-
 } // class InputStreamReader
 





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