GCC Bugzilla Bug 32541

On JikesRVM (and possibly other VMs), dacapo xalan performs lots of small IO using the default character encoding. OutputStreamWriter currently buffers characters when converting between character sets, but bypasses this when not converting. Applying the buffering uniformly speeds up dacapo xalan by 2x on JikesRVM.

Also, for single character IO, a new char array is allocated per IO operation. Avoiding this allocation gives a ~5% speedup.

--
Robin Garner
Dept. of Computer Science
Australian National University
http://cs.anu.edu.au/people/Robin.Garner/
diff -r -N -w -u -I '[$]Id:' --exclude='*.class' --exclude='.*' --exclude='*.orig' --exclude='*.rej' --exclude=CVS --exclude='#*' --exclude='*~' java/io/OutputStreamWriter.java java/io/OutputStreamWriter.java
--- java/io/OutputStreamWriter.java	2007-06-20 18:48:52.000000000 +1000
+++ java/io/OutputStreamWriter.java	2007-06-21 13:49:21.000000000 +1000
@@ -121,6 +121,8 @@
     throws UnsupportedEncodingException
   {
     this.out = out;
+	outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
+
     try 
       {
 	// Don't use NIO if avoidable
@@ -132,7 +134,7 @@
 	  }
 
 	/*
-	 * Workraround for encodings with a byte-order-mark.
+	 * Workaround for encodings with a byte-order-mark.
 	 * We only want to write it once per stream.
 	 */
 	try 
@@ -155,8 +157,6 @@
 	  {
 	  }
       
-	outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
-
 	Charset cs = EncodingHelper.getCharset(encoding_scheme);
 	if(cs == null)
 	  throw new UnsupportedEncodingException("Encoding "+encoding_scheme+
@@ -185,7 +185,7 @@
   public OutputStreamWriter (OutputStream out)
   {
     this.out = out;
-    outputBuffer = null;
+	outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
     try 
       {
 	String encoding = System.getProperty("file.encoding");
@@ -203,7 +203,6 @@
       {
 	encoder.onMalformedInput(CodingErrorAction.REPLACE);
 	encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
-	outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
       }
   }
 
@@ -345,7 +344,7 @@
     {
       byte[] b = new byte[count];
       for(int i=0;i<count;i++)
-	b[i] = (byte)((buf[offset+i] <= 0xFF)?buf[offset+i]:'?');
+	b[i] = nullConversion(buf[offset+i]);
       out.write(b);
     } else {
       try  {
@@ -369,6 +368,10 @@
     }
   }
 
+  private byte nullConversion(char c) {
+	  return (byte)((c <= 0xFF)?c:'?');
+  }
+
   /**
    * This method writes <code>count</code> bytes from the specified 
    * <code>String</code> starting at position <code>offset</code> into the
@@ -398,7 +401,20 @@
    */
   public void write (int ch) throws IOException
   {
-    write(new char[]{ (char)ch }, 0, 1);
+	  // No buffering, no encoding ... just pass through
+	  if (encoder == null && outputBuffer == null) {
+		  out.write(nullConversion((char)ch));
+	  } else {
+		  if (outputBuffer != null) {
+			  if (outputBuffer.remaining() == 0) {
+				  writeConvert(outputBuffer.array(), 0, BUFFER_SIZE);
+				  outputBuffer.clear();
+			  }
+			  outputBuffer.put((char)ch);
+		  } else {
+		      writeConvert(new char[]{ (char)ch }, 0, 1);
+		  }
+	  }
   }
 } // class OutputStreamWriter
 

Reply via email to