Re: version planning

Jochen Theodorou <[email protected]> Tue, 7 Jul 2026 13:47:57 +0200
Newsgroups gmane.comp.lang.groovy.devel
Message-ID <[email protected]>
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.
>=20
> Your mail crossed the implementation :-) That's exactly what landed as
> GROOVY-12127 on July 5: pure-Java "calibration ruler" benchmarks (intege=
r
> throughput, pointer-chase, allocation churn) now run inside every CI sui=
te
> shard, and the per-PR summary comment shows a hardware-calibrated speedu=
p
> column next to the raw one, plus a warning when the runner deviates >15%=
 from
> the baseline hardware. Your caveat =E2=80=94 that a runner isn't uniform=
 *within* a
> run either =E2=80=94 is fair; the planned refinement is a second ruler t=
hat 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=20
LambdaForms vs a
> 142-LF baseline JVM (deterministic, reproducible):
>=20
>    arity diversity (arities 1-8, all-Object args)     +136   (~17 LF/ari=
ty)
>    primitive arg diversity (8 primitive shapes)       +110   (~13 LF/sha=
pe)
>    one (R,int)Object call site (control)               +29
>    primitive RETURN diversity (vs uniform int +14)     +27    (~2 LF eac=
h)
>    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:
>=20
> 1. My W2 proposal (erase reference types in indy descriptors) is dead =
=E2=80=94 the
>     JVM already shares LambdaForms across reference-typed shapes, so era=
sure
>     would buy roughly nothing. Your skepticism was correct; no compiler =
change
>     should be written for that.
>=20
> 2. Your mismatch theory is confirmed, with a refinement: the callsite<->=
target
>     adaptation cost is real but specifically for the PRIMITIVE dimension=
s of
>     MethodType (boxing adaptations and per-arity forms). Reference-type
>     mismatches fold into shared forms for free. LambdaForms are shared a=
cross
>     call sites of identical shape =E2=80=94 the cost is per SHAPE, not p=
er site.

per shape was clear to me. The Reference-type mismatch being essentially=
=20
free but not primitives is kind of surprising. I mean it is clear to me=20
that the primitives do cost, but reference types being free not so much.=
=20
This means asType adaption and explicitCastArguments does not cost? Also=
=20
interesting would be the cost of inserting and dropping arguments in=20
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 ide=
a): an
>     (Object, Object[])Object cold dispatcher erases both expensive dimen=
sions
>     at once =E2=80=94 one shape for every arity and every primitive patt=
ern =E2=80=94 which is
>     precisely why reflection is cold-fast. The specialised primitive sha=
pes
>     then get paid lazily, only by the sites that earn promotion to hot.

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

bye Jochen