From ad3a88d861ecb4c55a38da4f6b65d03d6e66e4fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Szathma=CC=81ry?= Date: Sun, 13 Dec 2015 22:46:33 +0100 Subject: [PATCH 1/2] avoid buffer slicing in decodeString Yields ~10% improvement in included Benchmark. --- src/main/java/com/maxmind/db/Decoder.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/maxmind/db/Decoder.java b/src/main/java/com/maxmind/db/Decoder.java index 090caa3a..a4f94da1 100644 --- a/src/main/java/com/maxmind/db/Decoder.java +++ b/src/main/java/com/maxmind/db/Decoder.java @@ -15,6 +15,8 @@ * This class CANNOT be shared between threads */ final class Decoder { + private static final Charset UTF_8 = Charset.forName("UTF-8"); + // XXX - This is only for unit testings. We should possibly make a // constructor to set this boolean POINTER_TEST_HACK = false; @@ -183,9 +185,11 @@ private Result decodePointer(int ctrlByte, int offset) { } private String decodeString(int size) { - ByteBuffer buffer = this.buffer.slice(); - buffer.limit(size); - return Charset.forName("UTF-8").decode(buffer).toString(); + int oldLimit = buffer.limit(); + buffer.limit(buffer.position() + size); + String s = UTF_8.decode(buffer).toString(); + buffer.limit(oldLimit); + return s; } private IntNode decodeUint16(int size) { From 61e98ede2f6b4fb02a44bcf08fbff7c4a1a5ff27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Szathma=CC=81ry?= Date: Mon, 14 Dec 2015 00:04:07 +0100 Subject: [PATCH 2/2] decodeString: reuse CharsetDecoder Avoids ThreadLocal lookups in Charset#decode, another ~5% improvement on Benchmark. --- src/main/java/com/maxmind/db/Decoder.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/maxmind/db/Decoder.java b/src/main/java/com/maxmind/db/Decoder.java index a4f94da1..dbb37b16 100644 --- a/src/main/java/com/maxmind/db/Decoder.java +++ b/src/main/java/com/maxmind/db/Decoder.java @@ -3,7 +3,9 @@ import java.io.IOException; import java.math.BigInteger; import java.nio.ByteBuffer; +import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -24,6 +26,8 @@ final class Decoder { private final ObjectMapper objectMapper; + private final CharsetDecoder utfDecoder = UTF_8.newDecoder(); + private final ByteBuffer buffer; static enum Type { @@ -184,10 +188,10 @@ private Result decodePointer(int ctrlByte, int offset) { return new Result(new LongNode(pointer), offset + pointerSize); } - private String decodeString(int size) { + private String decodeString(int size) throws CharacterCodingException { int oldLimit = buffer.limit(); buffer.limit(buffer.position() + size); - String s = UTF_8.decode(buffer).toString(); + String s = utfDecoder.decode(buffer).toString(); buffer.limit(oldLimit); return s; }