diff --git a/core/trino-main/src/main/java/io/trino/util/JsonUtil.java b/core/trino-main/src/main/java/io/trino/util/JsonUtil.java index ac6bcacd267..0c8ae3a1b52 100644 --- a/core/trino-main/src/main/java/io/trino/util/JsonUtil.java +++ b/core/trino-main/src/main/java/io/trino/util/JsonUtil.java @@ -63,6 +63,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; +import java.io.StringReader; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; @@ -105,6 +106,9 @@ public final class JsonUtil { + // StringReader outperforms InputStreamReader for small inputs. Limit based on Jackson benchmarks {@link https://github.com/FasterXML/jackson-benchmarks/pull/9} + private static final int STRING_READER_LENGTH_LIMIT = 8192; + private JsonUtil() {} // This object mapper is constructed without .configure(ORDER_MAP_ENTRIES_BY_KEYS, true) because @@ -123,6 +127,15 @@ public static JsonFactory createJsonFactory() public static JsonParser createJsonParser(JsonFactory factory, Slice json) throws IOException { + // Jackson tries to detect the character encoding automatically when using InputStream + // so we pass StringReader or an InputStreamReader instead. + // Despite the https://github.com/FasterXML/jackson-core/pull/1081, the below performance optimization + // is still valid for small inputs. + if (json.length() < STRING_READER_LENGTH_LIMIT) { + // StringReader is more performant than InputStreamReader for small inputs + return factory.createParser(new StringReader(json.toStringUtf8())); + } + return factory.createParser(new InputStreamReader(json.getInput(), UTF_8)); }