Improve AppendableWriter performance (#1706)

* Improve AppendableWriter performance

Override methods which by default create char arrays or convert
CharSequences to Strings.
This is not necessary for AppendableWriter because it can directly
append these values to the Appendable delegate.

* Add test for Streams.writerForAppendable
This commit is contained in:
Marcono1234 2022-07-31 23:46:43 +02:00 committed by GitHub
parent a4290c52e0
commit 5f2513a407
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 89 additions and 2 deletions

View File

@ -93,12 +93,31 @@ public final class Streams {
appendable.append(currentWrite, offset, offset + length);
}
@Override public void flush() {}
@Override public void close() {}
// Override these methods for better performance
// They would otherwise unnecessarily create Strings or char arrays
@Override public void write(int i) throws IOException {
appendable.append((char) i);
}
@Override public void flush() {}
@Override public void close() {}
@Override public void write(String str, int off, int len) throws IOException {
// Appendable.append turns null -> "null", which is not desired here
$Gson$Preconditions.checkNotNull(str);
appendable.append(str, off, off + len);
}
@Override public Writer append(CharSequence csq) throws IOException {
appendable.append(csq);
return this;
}
@Override public Writer append(CharSequence csq, int start, int end) throws IOException {
appendable.append(csq, start, end);
return this;
}
/**
* A mutable char sequence pointing at a single char[].

View File

@ -0,0 +1,68 @@
package com.google.gson.internal;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.Writer;
import org.junit.Test;
public class StreamsTest {
@Test
public void testWriterForAppendable() throws IOException {
StringBuilder stringBuilder = new StringBuilder();
Writer writer = Streams.writerForAppendable(stringBuilder);
writer.append('a');
writer.append('\u1234');
writer.append("test");
writer.append(null); // test custom null handling mandated by `append`
writer.append("abcdef", 2, 4);
writer.append(null, 1, 3); // test custom null handling mandated by `append`
writer.append(',');
writer.write('a');
writer.write('\u1234');
// Should only consider the 16 low-order bits
writer.write(0x4321_1234);
writer.append(',');
writer.write("chars".toCharArray());
try {
writer.write((char[]) null);
fail();
} catch (NullPointerException e) {
}
writer.write("chars".toCharArray(), 1, 2);
try {
writer.write((char[]) null, 1, 2);
fail();
} catch (NullPointerException e) {
}
writer.append(',');
writer.write("string");
try {
writer.write((String) null);
fail();
} catch (NullPointerException e) {
}
writer.write("string", 1, 2);
try {
writer.write((String) null, 1, 2);
fail();
} catch (NullPointerException e) {
}
String actualOutput = stringBuilder.toString();
assertEquals("a\u1234testnullcdul,a\u1234\u1234,charsha,stringtr", actualOutput);
writer.flush();
writer.close();
// flush() and close() calls should have had no effect
assertEquals(actualOutput, stringBuilder.toString());
}
}