Skip to content

Commit 4d0ea4c

Browse files
committed
Decoder perf: reuse ObjectMapper, static ptr offsets
ObjectMapper is in fact thread-safe (see https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/ObjectMapper.html). Yields a ~3-5% improvement in Benchmark. Also, pointer offsets should be static. Negligible perf impact, more of a stylistic improvement.
1 parent 52bb944 commit 4d0ea4c

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

src/main/java/com/maxmind/db/Decoder.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@
1717
* This class CANNOT be shared between threads
1818
*/
1919
final class Decoder {
20+
2021
private static final Charset UTF_8 = Charset.forName("UTF-8");
2122

23+
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
24+
2225
// XXX - This is only for unit testings. We should possibly make a
2326
// constructor to set this
2427
boolean POINTER_TEST_HACK = false;
25-
private final long pointerBase;
2628

27-
private final ObjectMapper objectMapper;
29+
private final long pointerBase;
2830

2931
private final CharsetDecoder utfDecoder = UTF_8.newDecoder();
3032

@@ -78,7 +80,6 @@ void setOffset(int offset) {
7880
Decoder(ByteBuffer buffer, long pointerBase) {
7981
this.pointerBase = pointerBase;
8082
this.buffer = buffer;
81-
this.objectMapper = new ObjectMapper();
8283
}
8384

8485
Result decode(int offset) throws IOException {
@@ -175,15 +176,15 @@ private Result decodeByType(Type type, int offset, int size)
175176
}
176177
}
177178

178-
private final int[] pointerValueOffset = {0, 0, 1 << 11,
179+
private static final int[] POINTER_VALUE_OFFSETS = {0, 0, 1 << 11,
179180
(1 << 19) + ((1) << 11), 0};
180181

181182
private Result decodePointer(int ctrlByte, int offset) {
182183
int pointerSize = ((ctrlByte >>> 3) & 0x3) + 1;
183184
int base = pointerSize == 4 ? (byte) 0 : (byte) (ctrlByte & 0x7);
184185
int packed = this.decodeInteger(base, pointerSize);
185186
long pointer = packed + this.pointerBase
186-
+ this.pointerValueOffset[pointerSize];
187+
+ POINTER_VALUE_OFFSETS[pointerSize];
187188

188189
return new Result(new LongNode(pointer), offset + pointerSize);
189190
}
@@ -270,7 +271,7 @@ private static BooleanNode decodeBoolean(int size)
270271
}
271272

272273
private Result decodeArray(int size, int offset) throws IOException {
273-
ArrayNode array = this.objectMapper.createArrayNode();
274+
ArrayNode array = OBJECT_MAPPER.createArrayNode();
274275

275276
for (int i = 0; i < size; i++) {
276277
Result r = this.decode(offset);
@@ -282,7 +283,7 @@ private Result decodeArray(int size, int offset) throws IOException {
282283
}
283284

284285
private Result decodeMap(int size, int offset) throws IOException {
285-
ObjectNode map = this.objectMapper.createObjectNode();
286+
ObjectNode map = OBJECT_MAPPER.createObjectNode();
286287

287288
for (int i = 0; i < size; i++) {
288289
Result keyResult = this.decode(offset);

0 commit comments

Comments
 (0)