#863 compute initial capacity for StringBuilderWriter

This commit is contained in:
Simulant 2024-02-24 21:21:06 +01:00
parent 6660e40915
commit 06778bd2d9
3 changed files with 30 additions and 4 deletions

View File

@ -1694,7 +1694,10 @@ public class JSONArray implements Iterable<Object> {
*/ */
@SuppressWarnings("resource") @SuppressWarnings("resource")
public String toString(int indentFactor) throws JSONException { public String toString(int indentFactor) throws JSONException {
Writer sw = new StringBuilderWriter(); // each value requires a comma, so multiply the count my 2
// We don't want to oversize the initial capacity
int initialSize = myArrayList.size() * 2;
Writer sw = new StringBuilderWriter(Math.max(initialSize, 16));
return this.write(sw, indentFactor, 0).toString(); return this.write(sw, indentFactor, 0).toString();
} }

View File

@ -2226,7 +2226,10 @@ public class JSONObject {
*/ */
@SuppressWarnings("resource") @SuppressWarnings("resource")
public static String quote(String string) { public static String quote(String string) {
Writer sw = new StringBuilderWriter(); if (string == null || string.isEmpty()) {
return "\"\"";
}
Writer sw = new StringBuilderWriter(string.length() + 2);
try { try {
return quote(string, sw).toString(); return quote(string, sw).toString();
} catch (IOException ignored) { } catch (IOException ignored) {
@ -2557,7 +2560,10 @@ public class JSONObject {
*/ */
@SuppressWarnings("resource") @SuppressWarnings("resource")
public String toString(int indentFactor) throws JSONException { public String toString(int indentFactor) throws JSONException {
Writer w = new StringBuilderWriter(); // 6 characters are the minimum to serialise a key value pair e.g.: "k":1,
// and we don't want to oversize the initial capacity
int initialSize = map.size() * 6;
Writer w = new StringBuilderWriter(Math.max(initialSize, 16));
return this.write(w, indentFactor, 0).toString(); return this.write(w, indentFactor, 0).toString();
} }
@ -2699,6 +2705,10 @@ public class JSONObject {
int indentFactor, int indent) throws JSONException, IOException { int indentFactor, int indent) throws JSONException, IOException {
if (value == null || value.equals(null)) { if (value == null || value.equals(null)) {
writer.write("null"); writer.write("null");
} else if (value instanceof String) {
// assuming most values are Strings, so testing it earlier
quote(value.toString(), writer);
return writer;
} else if (value instanceof JSONString) { } else if (value instanceof JSONString) {
Object o; Object o;
try { try {
@ -2706,7 +2716,7 @@ public class JSONObject {
} catch (Exception e) { } catch (Exception e) {
throw new JSONException(e); throw new JSONException(e);
} }
writer.write(o != null ? o.toString() : quote(value.toString())); writer.write(o != null ? o.toString() : "\"\"");
} else if (value instanceof Number) { } else if (value instanceof Number) {
// not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary // not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary
final String numberAsString = numberToString((Number) value); final String numberAsString = numberToString((Number) value);

View File

@ -18,6 +18,19 @@ class StringBuilderWriter extends Writer {
lock = builder; lock = builder;
} }
/**
* Create a new string builder writer using the specified initial string-builder buffer size.
*
* @param initialSize The number of {@code char} values that will fit into this buffer
* before it is automatically expanded
*
* @throws IllegalArgumentException If {@code initialSize} is negative
*/
StringBuilderWriter(int initialSize) {
builder = new StringBuilder(initialSize);
lock = builder;
}
@Override @Override
public void write(int c) { public void write(int c) {
builder.append((char) c); builder.append((char) c);