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