You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: sdk/cosmos/azure-cosmos/benchmark-results/PR-DESCRIPTION.md
+32-30Lines changed: 32 additions & 30 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,31 +2,33 @@
2
2
3
3
### Motivation
4
4
5
-
JFR profiling of the baseline (`main`) under high-concurrency gateway workloads revealed that `HashMap`-related allocations (`HashMap$Node`, `HashMap`, `HashMap$ValueIterator`) and HTTP header collections (`DefaultHeaders$HeaderEntry`, `HttpHeader`) account for a significant portion of total allocation pressure — approximately **8–15%** of total sampled allocation weight depending on concurrency.
5
+
JFR profiling of the baseline (`main`) under high-concurrency gateway workloads revealed that `HashMap`-related allocations (`HashMap$Node`, `HashMap`, `HashMap$ValueIterator`) and HTTP header collections (`DefaultHeaders$HeaderEntry`, `HttpHeader`) account for a significant portion of total allocation pressure -- approximately **8-15%** of total sampled allocation weight depending on concurrency.
6
6
7
-
**Key findings from baseline JFR recordings** (c128 Read HTTP/1, `ObjectAllocationSample`):
> **What is "Alloc Weight"?** JFR `ObjectAllocationSample` uses statistical sampling. The `weight` field is the **estimated cumulative bytes allocated** over the recording duration -- NOT heap residency. Most objects are short-lived and immediately GC'd. For reference, the JVM heap was 8 GB committed / ~5 GB used, while total allocation throughput was ~4 GB/s (typical for reactive workloads with high object churn).
10
+
11
+
| Class | Cumulative Alloc (10 min) | % of Total Alloc |
1.`HashMap<>()` default initial capacity (16) forces 1–2 resize+rehash cycles for typical gateway responses with 20–30 headers
22
-
2.`StoreResponse` constructor converts `HttpHeaders`→`Map<String, String>` via `HttpUtils.asMap()` on every response, allocating a throwaway `HashMap$ValueIterator` and rebuilding `HashMap$Node` entries
23
+
1.`HashMap<>()` default initial capacity (16) forces 1-2 resize+rehash cycles for typical gateway responses with 20-30 headers, creating throwaway `HashMap$Node[]` arrays and re-hashed `HashMap$Node` entries
24
+
2.`StoreResponse` constructor converts `HttpHeaders`to`Map<String, String>` via `HttpUtils.asMap()` on every response, allocating a throwaway `HashMap$ValueIterator` and rebuilding `HashMap$Node` entries
23
25
3.`HttpHeaders` in `RxGatewayStoreModel.getHttpRequestHeaders()` is undersized, causing internal HashMap resize
24
26
4. Redundant `toLowerCase()` calls on header keys that are already normalized
25
27
26
28
### Changes
27
29
28
30
1.**Right-sized HashMap initial capacity**: `HashMap<>(32)` instead of `HashMap<>()` in `RxDocumentServiceRequest`, and `mapCapacityForSize()` helper in `HttpUtils` to avoid rehashing
29
-
2.**Eliminate HashMap → HttpHeaders → HashMap round-trip**: `StoreResponse` now accepts `HttpHeaders` directly, removing intermediate `asMap()` conversion that created throwaway `HashMap$ValueIterator` and `HashMap$Node` arrays
31
+
2.**Eliminate HashMap to HttpHeaders to HashMap round-trip**: `StoreResponse` now accepts `HttpHeaders` directly, removing intermediate `asMap()` conversion that created throwaway `HashMap$ValueIterator` and `HashMap$Node` arrays
30
32
3.**Pre-sized HttpHeaders in `RxGatewayStoreModel`**: sized to `defaultHeaders.size() + headers.size()` to avoid internal HashMap resize
31
33
4.**Remove redundant `toLowerCase()` calls**: `HttpHeaders.set()` already normalizes keys; callers no longer double-normalize creating extra `String` objects
> Note: `HashMap` object weight increased (18 -> 99 GB) due to JFR `ObjectAllocationSample` being statistical — pre-sized HashMap objects are sampled at a different rate than resize-triggered ones. The overall `HashMap$Node` reduction (23%) confirms fewer resize/rehash operations.
86
+
> Note: `HashMap` object allocation weight increased (18 to 99 GB) -- this is a JFR sampling artifact. Pre-sized HashMap objects are sampled at a different rate than resize-triggered ones. The `HashMap$Node` reduction (23%) confirms fewer resize/rehash operations, which is the actual goal.
-**Write throughput**: neutral (+/-0.2% at high concurrency), confirming no regression on the write path
133
135
- The changes are a **net improvement in allocation efficiency** with **no measurable throughput regression** once run-order artifacts are accounted for.
0 commit comments