On 7/7/26 11:48, Paul King wrote:
[...]
My idea would be to have a baseline benchmark in Groovy unrelated code
in pure Java. And then adjust everything to be relative to that.

Your mail crossed the implementation :-) That's exactly what landed as
GROOVY-12127 on July 5: pure-Java "calibration ruler" benchmarks (integer
throughput, pointer-chase, allocation churn) now run inside every CI suite
shard, and the per-PR summary comment shows a hardware-calibrated speedup
column next to the raw one, plus a warning when the runner deviates >15% from
the baseline hardware. Your caveat — that a runner isn't uniform *within* a
run either — is fair; the planned refinement is a second ruler that sorts to
the end of each suite's execution so we can report intra-run drift too.

nice

[...]> Small generated workloads, each varying ONE dimension, delta LambdaForms vs a
142-LF baseline JVM (deterministic, reproducible):

   arity diversity (arities 1-8, all-Object args)     +136   (~17 LF/arity)
   primitive arg diversity (8 primitive shapes)       +110   (~13 LF/shape)
   one (R,int)Object call site (control)               +29
   primitive RETURN diversity (vs uniform int +14)     +27    (~2 LF each)
   8 sites, all-Object args (control)                  +17
   reference arg diversity (8 distinct classes)        +16    (~free)
   reference return diversity                          +12    (~free)
   32 sites vs 1 site, identical shape+target        +29 vs +29  (0 per site)

interesting, though not sure I interpret the numbers correctly

Conclusions:

1. My W2 proposal (erase reference types in indy descriptors) is dead — the
    JVM already shares LambdaForms across reference-typed shapes, so erasure
    would buy roughly nothing. Your skepticism was correct; no compiler change
    should be written for that.

2. Your mismatch theory is confirmed, with a refinement: the callsite<->target
    adaptation cost is real but specifically for the PRIMITIVE dimensions of
    MethodType (boxing adaptations and per-arity forms). Reference-type
    mismatches fold into shared forms for free. LambdaForms are shared across
    call sites of identical shape — the cost is per SHAPE, not per site.

per shape was clear to me. The Reference-type mismatch being essentially free but not primitives is kind of surprising. I mean it is clear to me that the primitives do cost, but reference types being free not so much. This means asType adaption and explicitCastArguments does not cost? Also interesting would be the cost of inserting and dropping arguments in terms of Lambda forms

3. This strengthens the cold-tier direction you're already circling (the
    reflection/MOP-dispatching cold path, your hidden-class template idea): an
    (Object, Object[])Object cold dispatcher erases both expensive dimensions
    at once — one shape for every arity and every primitive pattern — which is
    precisely why reflection is cold-fast. The specialised primitive shapes
    then get paid lazily, only by the sites that earn promotion to hot.

still possible that creating those hidden classes costs too much though. Also we need an efficient lookup for those, since we would have one per "called" method in the receiver globally... well per module and classloader would also work for JPMS compatibility.

bye Jochen

Reply via email to