Problem
On short operations, statement building dominates Storm's per-operation allocation. Precise per-thread allocation counters over a warmed hot loop of a by-primary-key read (PostgreSQL, three-column entity) split as:
| phase |
B/op |
| builder chain (DSL objects) |
1,623 |
| build, i.e. SQL generation |
8,016 |
| full operation (execute + hydrate) |
10,908 |
| hand-written JDBC, entire operation |
1,894 |
Roughly 73% of the operation's allocation happens in the build phase — about 6.4 KB per call beyond the builder chain — even though the compiled SQL itself is cached. JMH's allocation profiler shows the same pattern across every short workload, and the excess correlates with the small latency deltas to the leanest implementations on point operations (single-row read, projection, dynamic query, read-modify-update, create-then-amend): roughly 5–7 KB/op of additional allocation tracks a 4–17 µs/op gap.
Proposal
Profile the build path (template processing through SqlTemplateImpl.process and statement preparation) with allocation events and itemize the ~6.4 KB, then trim the dominant producers. Likely candidates, to be confirmed by measurement rather than assumption:
- per-call construction of compilation keys, element lists, and template fragments for templates whose compiled form is already cached;
- binder and parameter-list allocations that could be sized or reused for cached templates;
- intermediate string building in fragments that end up identical for every execution of the same template.
A win here lifts every short workload at once. Multi-row reads are unaffected: their per-row hydration already dominates and is competitive.
Problem
On short operations, statement building dominates Storm's per-operation allocation. Precise per-thread allocation counters over a warmed hot loop of a by-primary-key read (PostgreSQL, three-column entity) split as:
Roughly 73% of the operation's allocation happens in the build phase — about 6.4 KB per call beyond the builder chain — even though the compiled SQL itself is cached. JMH's allocation profiler shows the same pattern across every short workload, and the excess correlates with the small latency deltas to the leanest implementations on point operations (single-row read, projection, dynamic query, read-modify-update, create-then-amend): roughly 5–7 KB/op of additional allocation tracks a 4–17 µs/op gap.
Proposal
Profile the build path (template processing through
SqlTemplateImpl.processand statement preparation) with allocation events and itemize the ~6.4 KB, then trim the dominant producers. Likely candidates, to be confirmed by measurement rather than assumption:A win here lifts every short workload at once. Multi-row reads are unaffected: their per-row hydration already dominates and is competitive.