Skip to content

Parser: reduce substring + java.time allocation churn in numeric/timestamp parsing #568

Description

@brunoborges

Summary

After regex matching, the next biggest allocation source in the parser is temporary String / byte[] and java.time objects created while parsing numeric and timestamp fields. Each parsed line slices substrings and builds intermediate java.time objects that are immediately discarded.

Evidence (JFR settings=profile, ~28s run)

Workload: sample Main parsing a 195 MB JDK8 ParallelGC rolling log (gclogs/rolling/jdk8/aagl_prd/gc.log), -Xmx1500m, G1, Java 25 (GraalVM 25.0.3). ~19,985 MB sampled allocations.

Allocation by site:

Site Share
java.lang.String.substring(int, int) 8.06%
com.microsoft.gctoolkit.parser.AbstractLogTrace.convertToDouble(String) 3.33%
java.time.LocalDate.ofEpochDay(long) 3.29%
java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.parse(...) 2.51%
com.microsoft.gctoolkit.time.DateTimeStamp.dateFromString(String) 1.63%
jdk.internal.math.FloatingDecimal.readJavaFormatString(...) 1.47%
jdk.internal.math.FloatingDecimal.copyDigits(...) 1.23%

Allocation by class (related): byte[] 7.98%, java.lang.String 3.30%, java.time.format.Parsed 2.61%, LocalDateTime 2.05%, LocalDate 1.87%, LocalTime 1.56%.

Suggested fixes

  • Parse numerics directly off the matched region using index offsets rather than substring(...) + Double.parseDouble(...) (avoids String + byte[] + FloatingDecimal churn).
  • Avoid building intermediate java.time objects on the hot path; reuse a preconfigured DateTimeFormatter and resolve straight to an epoch value. DateTimeStamp.dateFromString and AbstractLogTrace.convertToDouble are good entry points.

Expected impact

Reduces ~15–20% of sampled allocation pressure (substring + java.time + FloatingDecimal). Complements the Matcher-reuse work; GC is already healthy (98.76% throughput) so this improves allocation throughput / CPU, not pauses.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions