Skip to content

Commit b002c84

Browse files
authored
Merge pull request #9 from schlosna/ds/ByteSourceBenchmark
Add StringReader input benchmark
2 parents 67356bc + 2f689f6 commit b002c84

File tree

1 file changed

+73
-14
lines changed

1 file changed

+73
-14
lines changed

src/main/java/com/fasterxml/jackson/perf/json/JsonArbitraryFieldNameBenchmark.java

Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,15 @@
1818
import org.openjdk.jmh.annotations.Scope;
1919
import org.openjdk.jmh.annotations.Setup;
2020
import org.openjdk.jmh.annotations.State;
21+
import org.openjdk.jmh.runner.Runner;
22+
import org.openjdk.jmh.runner.options.OptionsBuilder;
23+
import org.openjdk.jmh.runner.options.TimeValue;
2124

2225
import java.io.ByteArrayInputStream;
2326
import java.io.IOException;
2427
import java.io.InputStreamReader;
28+
import java.io.StringReader;
29+
import java.nio.charset.Charset;
2530
import java.nio.charset.StandardCharsets;
2631
import java.util.Map;
2732
import java.util.concurrent.ThreadLocalRandom;
@@ -51,7 +56,8 @@ <F extends JsonFactory, B extends TSFBuilder<F, B>> B apply(B factory) {
5156
<F extends JsonFactory, B extends TSFBuilder<F, B>> B apply(B factory) {
5257
return factory.disable(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES);
5358
}
54-
};
59+
},
60+
;
5561

5662
abstract <F extends JsonFactory, B extends TSFBuilder<F, B>> B apply(B factory);
5763
}
@@ -62,38 +68,79 @@ <F extends JsonFactory, B extends TSFBuilder<F, B>> B apply(B factory) {
6268
public enum InputType {
6369
INPUT_STREAM() {
6470
@Override
65-
JsonParser create(JsonFactory factory, Supplier<String> jsonSupplier) throws IOException {
66-
return factory.createParser(new ByteArrayInputStream(jsonSupplier.get().getBytes(StandardCharsets.UTF_8)));
71+
JsonParser create(JsonFactory factory, Supplier<byte[]> bytesSupplier) throws IOException {
72+
return factory.createParser(new ByteArrayInputStream(bytesSupplier.get()));
6773
}
6874
},
6975
READER() {
7076
@Override
71-
JsonParser create(JsonFactory factory, Supplier<String> jsonSupplier) throws IOException {
72-
// Instead of using 'new StringReader(jsonSupplier.get())', we construct an InputStreamReader
77+
JsonParser create(JsonFactory factory, Supplier<byte[]> bytesSupplier) throws IOException {
78+
// Instead of using 'new StringReader(bytesSupplier.get())', we construct an InputStreamReader
7379
// to more closely match overhead of INPUT_STREAM for comparison.
7480
return factory.createParser(new InputStreamReader(
75-
new ByteArrayInputStream(jsonSupplier.get().getBytes(StandardCharsets.UTF_8)),
81+
new ByteArrayInputStream(bytesSupplier.get()),
7682
StandardCharsets.UTF_8));
7783
}
78-
};
84+
},
85+
STRING_READER() {
86+
@Override
87+
JsonParser create(JsonFactory factory, Supplier<byte[]> jsonSupplier) throws IOException {
88+
StringReader reader = new StringReader(new String(jsonSupplier.get(), Charset.forName("UTF-8")));
89+
return factory.createParser(reader);
90+
}
91+
},
92+
;
7993

80-
abstract JsonParser create(JsonFactory factory, Supplier<String> jsonSupplier) throws IOException;
94+
abstract JsonParser create(JsonFactory factory, Supplier<byte[]> jsonSupplier) throws IOException;
8195
}
8296

8397
public enum InputShape {
98+
KEY_MAP(
99+
new TypeReference<Map<String, Boolean>>() {
100+
},
101+
() -> "{\"key\":true}"),
84102
RANDOM_KEY_MAP(
85-
new TypeReference<Map<String, Boolean>>() {},
103+
new TypeReference<Map<String, Boolean>>() {
104+
},
86105
() -> "{\"" + ThreadLocalRandom.current().nextInt() + "\":true}"),
87106
BEAN_WITH_RANDOM_KEY_MAP(
88-
new TypeReference<SimpleClass>() {},
107+
new TypeReference<SimpleClass>() {
108+
},
89109
() -> "{\"fieldWithMap\":{\"" + ThreadLocalRandom.current().nextInt()
90-
+ "\":true},\"stringOne\":\"a\",\"stringTwo\":\"a\",\"stringThree\":\"a\"}");
110+
+ "\":true},\"stringOne\":\"a\",\"stringTwo\":\"a\",\"stringThree\":\"a\"}"),
111+
BEAN_WITH_LARGE_KEY_MAP(
112+
new TypeReference<SimpleClass>() {
113+
},
114+
new Supplier<String>() {
115+
private final String json = generateSimpleInstanceJson(10_000);
116+
117+
@Override
118+
public String get() {
119+
return json;
120+
}
121+
}
122+
),
123+
;
124+
125+
private static String generateSimpleInstanceJson(int n) {
126+
StringBuilder builder = new StringBuilder();
127+
builder.append("{\"fieldWithMap\":{");
128+
for (int i = 0; i < n; i++) {
129+
builder.append("\"").append(i).append("\":").append(i % 2 == 0);
130+
if (i < n-1) {
131+
builder.append(',');
132+
}
133+
}
134+
builder.append("},\"stringOne\":\"a\",\"stringTwo\":\"a\",\"stringThree\":\"a\"}");
135+
return builder.toString();
136+
}
91137

92138
private final TypeReference<?> typereference;
93-
private final Supplier<String> jsonSupplier;
139+
private final Supplier<byte[]> bytesSupplier;
140+
94141
InputShape(TypeReference<?> typereference, Supplier<String> jsonSupplier) {
95142
this.typereference = typereference;
96-
this.jsonSupplier = jsonSupplier;
143+
this.bytesSupplier = () -> jsonSupplier.get().getBytes(StandardCharsets.UTF_8);
97144
}
98145
}
99146

@@ -121,7 +168,7 @@ public void setup() {
121168

122169
@Benchmark
123170
public Object parse() throws IOException {
124-
try (JsonParser parser = type.create(factory, shape.jsonSupplier)) {
171+
try (JsonParser parser = type.create(factory, shape.bytesSupplier)) {
125172
return reader.readValue(parser);
126173
}
127174
}
@@ -140,4 +187,16 @@ public static final class SimpleClass {
140187
@JsonProperty("stringThree")
141188
public String stringThree;
142189
}
190+
191+
public static void main(String[] _args) throws Exception {
192+
new Runner(new OptionsBuilder()
193+
.include(JsonArbitraryFieldNameBenchmark.class.getName())
194+
.warmupIterations(2)
195+
.warmupTime(TimeValue.seconds(5))
196+
.measurementIterations(4)
197+
.measurementTime(TimeValue.seconds(5))
198+
.mode(Mode.AverageTime)
199+
.forks(1)
200+
.build()).run();
201+
}
143202
}

0 commit comments

Comments
 (0)