Skip to content

Commit ab8b2ff

Browse files
committed
Optimize InstantDeserializer replaceZeroOffsetAsZIfNecessary
Avoid expensive regex matcher allocations when replacing zero offset with 'Z'. OpenJDK 17 on x64 Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz Benchmark Mode Cnt Score Error Units InstantDeserializerBenchmark.index avgt 5 19.543 ± 1.384 ns/op InstantDeserializerBenchmark.regex avgt 5 155.081 ± 3.234 ns/op OpenJDK 17 on aarch64 Apple M1 Pro aarch64 Benchmark Mode Cnt Score Error Units InstantDeserializerBenchmark.index avgt 5 16.855 ± 0.537 ns/op InstantDeserializerBenchmark.regex avgt 5 58.155 ± 1.444 ns/op
1 parent 7410000 commit ab8b2ff

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/InstantDeserializer.java

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,6 @@ public class InstantDeserializer<T extends Temporal>
5454
{
5555
private static final long serialVersionUID = 1L;
5656

57-
/**
58-
* Constants used to check if the time offset is zero. See [jackson-modules-java8#18]
59-
*
60-
* @since 2.9.0
61-
*/
62-
private static final Pattern ISO8601_UTC_ZERO_OFFSET_SUFFIX_REGEX = Pattern.compile("\\+00:?(00)?$");
63-
6457
/**
6558
* Constants used to check if ISO 8601 time string is colonless. See [jackson-modules-java8#131]
6659
*
@@ -226,7 +219,7 @@ public T deserialize(JsonParser parser, DeserializationContext context) throws I
226219
return (T) parser.getEmbeddedObject();
227220

228221
case JsonTokenId.ID_START_ARRAY:
229-
return _deserializeFromArray(parser, context);
222+
return _deserializeFromArray(parser, context);
230223
}
231224
return _handleUnexpectedToken(context, parser, JsonToken.VALUE_STRING,
232225
JsonToken.VALUE_NUMBER_INT, JsonToken.VALUE_NUMBER_FLOAT);
@@ -337,12 +330,31 @@ private ZoneId getZone(DeserializationContext context)
337330
private String replaceZeroOffsetAsZIfNecessary(String text)
338331
{
339332
if (replaceZeroOffsetAsZ) {
340-
return ISO8601_UTC_ZERO_OFFSET_SUFFIX_REGEX.matcher(text).replaceFirst("Z");
333+
return replaceZeroOffsetAsZ(text);
341334
}
342335

343336
return text;
344337
}
345338

339+
private static String replaceZeroOffsetAsZ(String text)
340+
{
341+
int plusIndex = text.lastIndexOf('+');
342+
if (plusIndex < 0) {
343+
return text;
344+
}
345+
int maybeOffsetIndex = plusIndex + 1;
346+
int remaining = text.length() - maybeOffsetIndex;
347+
if (remaining < 2 || remaining == 3 || remaining > 5) {
348+
return text;
349+
}
350+
351+
String maybeOffset = text.substring(maybeOffsetIndex);
352+
if ("00".equals(maybeOffset) || "0000".equals(maybeOffset) || "00:00".equals(maybeOffset)) {
353+
return text.substring(0, plusIndex) + 'Z';
354+
}
355+
return text;
356+
}
357+
346358
// @since 2.13
347359
private String addInColonToOffsetIfMissing(String text)
348360
{

0 commit comments

Comments
 (0)