Skip to content

date optimization#1658

Open
luigi617 wants to merge 2 commits into
mainfrom
optimization-http-engine-date
Open

date optimization#1658
luigi617 wants to merge 2 commits into
mainfrom
optimization-http-engine-date

Conversation

@luigi617

Copy link
Copy Markdown
Collaborator

Summary

  • Pre-compute formatted signing dates in AwsSigningConfig to avoid repeated Instant.format() calls during SigV4 signing
  • Suppress fillInStackTrace on internal parser exceptions to eliminate expensive JVM stack walks during RFC-5322 date parsing

Motivation

Profiling sequential DynamoDB latency benchmarks revealed two date-related hotspots in the per-request signing and response handling paths:

  1. Repeated date formatting: Instant.format(TimestampFormat.ISO_8601_CONDENSED) was called 6 times per signing operation (in stringToSign, credentialScope, signingKey, and canonicalRequest), each time producing the same string from the same Instant.

  2. Exception-driven date parsing: The ClockSkewInterceptor parses the response Date header on every request via Instant.fromRfc5322(). The parser combinator's alt function uses exceptions for backtracking — matching the day name "Thu" requires throwing and catching 3 ParseException instances (for "Mon", "Tue", "Wed"). Each exception triggers Throwable.fillInStackTrace(), a native JNI call that walks the entire thread stack (~50+ frames deep in coroutine + middleware context), costing ~5-15µs per exception.

What changed

Date formatting (signing path):
AwsSigningConfig now exposes formattedSigningDate and formattedSigningDateShort properties, computed once at construction. All 6 call sites in BaseSigV4SignatureCalculator, Canonicalizer, RequestMutator, and SigV4SignatureCalculator use the pre-computed values.

Date parsing (response path):
Introduced NoTraceParseException as an expect/actual class:

  • JVM actual: overrides fillInStackTrace() to return this (no-op)
  • Native actual: plain subclass (stack traces are not expensive on Native)

All internal parser combinator throw sites (char(), tag(), oneOf(), takeMNDigitsT(), mnDigitsInRange(), fraction()) now throw NoTraceParseException. The final alt failure that may escape to user code retains the full ParseException with stack trace for diagnosability.

Benchmark Results

All benchmarks run on m7i.2xlarge instances with the following configuration:

  • Operations per batch: 100,000
  • Warmup batches: 3
  • Measurement batches: 5

E2E Latency (DynamoDB)

14 paired instances (base and target on same host).

DynamoDB PutItem

Metric Base (ms) Target (ms) Change
Average 4.36 4.34 -0.50%
P50 4.20 4.19 -0.27%
P90 4.93 4.88 -1.02%
P99 7.23 7.01 -3.01%

DynamoDB GetItem

Metric Base (ms) Target (ms) Change
Average 3.35 3.18 -4.92%
P50 3.20 3.05 -4.53%
P90 3.84 3.69 -3.90%
P99 6.40 5.98 -6.50%

Latency observations:

  • GetItem shows consistent improvement across all percentiles (-4.5% to -6.5%) — the date parsing optimization is directly visible since response handling (where ClockSkewInterceptor parses the Date header) represents a larger fraction of the shorter GET latency
  • PutItem shows modest tail-latency improvement (-3% at P99) — the signing date formatting optimization benefits both operations equally, but PUT latency is dominated by network round-trip for the larger request body
  • No CPU or memory regression — resource usage is effectively identical

E2E Throughput (S3)

This optimization targets per-request fixed costs (date format/parse), which are negligible relative to the I/O and crypto costs that dominate high-concurrency throughput workloads. No meaningful throughput change expected or observed.


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@luigi617 luigi617 added the no-changelog Indicates that a changelog entry isn't required for a pull request. Use sparingly. label Jul 15, 2026
@luigi617 luigi617 marked this pull request as ready for review July 15, 2026 03:53
@luigi617 luigi617 requested a review from a team as a code owner July 15, 2026 03:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog Indicates that a changelog entry isn't required for a pull request. Use sparingly.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant