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
Trimmable typemap startup currently spends most of the managed JNIEnvInit.Initialize budget loading and initializing generated managed typemap data.
Using the OTEL instrumentation from draft PR #11502 and viewing the data through Aspire, a Release/CoreCLR/trimmable HelloWorld run shows:
median jnienv.initialize: 99,591 us
median typemap.data.initialize: 62,103 us
typemap.data.initialize is roughly 2/3 of the observed JNIEnvInit.Initialize budget
This should be tracked separately from the broader trimmable typemap runtime performance work because it points at the generated managed typemap initialization path itself, not just app activation or steady-state lookup cost.
From 10 Release/CoreCLR/trimmable launches of samples/HelloWorld:
Metric
Count
Min
Median
Max
Mean
TotalTime ms
10
528.0
544.5
557.0
543.5
WaitTime ms
10
531.0
549.5
564.0
548.8
Host elapsed us
10
624504.0
661617.0
746665.0
667727.7
jnienv.initialize us
10
96694.2
99591.25
122651.1
101759.32
typemap.data.initialize us
10
60933.0
62103.2
82455.6
64033.28
10x LLVM-IR comparison data
After extending the same OTEL instrumentation to the existing LLVM-IR/CoreCLR typemap path, 10 Release/CoreCLR/LLVM-IR launches show:
Metric
Count
Min
Median
Max
Mean
TotalTime ms
10
470.0
480.5
492.0
480.2
WaitTime ms
10
473.0
485.0
494.0
484.4
Host elapsed us
10
577463.0
605775.0
757226.0
635601.4
LLVM span count
10
36.0
103.5
141.0
96.0
jnienv.initialize us
10
37423.2
38970.45
40533.8
39009.79
typemap.llvm.activation us
10
900.6
986.5
1096.3
994.73
typemap.llvm.lookup_jni_name.uncached us
10
78.7
93.3
127.9
99.24
Paired comparison
The directly paired startup boundary is jnienv.initialize. Trimmable is slower by about 60.6 ms median, and typemap.data.initialize accounts for about 62.1 ms median. That means the measured trimmable startup delta is almost entirely explained by generated typemap data initialization.
Metric
Trimmable median
LLVM-IR median
Delta
Ratio
TotalTime
544.5 ms
480.5 ms
+64.0 ms
1.13x
WaitTime
549.5 ms
485.0 ms
+64.5 ms
1.13x
Host elapsed
661,617 us
605,775 us
+55,842 us
1.09x
jnienv.initialize
99,591.25 us
38,970.45 us
+60,620.8 us
2.56x
Paired / analogous spans
Concept
Trimmable span
Trimmable median
LLVM-IR span
LLVM-IR median
Notes
JNI runtime init boundary
jnienv.initialize
99,591.25 us
jnienv.initialize
38,970.45 us
Directly comparable boundary.
Typemap data setup
typemap.data.initialize
62,103.2 us
none
-
LLVM-IR has no managed generated typemap assembly load equivalent. This is the main trimmable-only cost.
Runtime typemap object setup
typemap.initialize
4,249.3 us
none
-
Trimmable wraps generated dictionaries in runtime lookup structures.
Native registration setup
typemap.register_native_methods
169.9 us
built-in/native typemap path
-
Not currently separated in LLVM-IR; native path is implicit.
Java object -> managed peer creation
typemap.peer.create
1,005.4 us
typemap.llvm.activation
986.5 us
Similar order of magnitude for first activity-related activation.
Framework ACW trimming and ProGuard generator improvements may reduce payload size and generated wrapper pressure, but this issue is specifically about the cost of typemap.data.initialize during JNIEnvInit.Initialize.
Summary
Trimmable typemap startup currently spends most of the managed
JNIEnvInit.Initializebudget loading and initializing generated managed typemap data.Using the OTEL instrumentation from draft PR #11502 and viewing the data through Aspire, a Release/CoreCLR/trimmable
HelloWorldrun shows:jnienv.initialize: 99,591 ustypemap.data.initialize: 62,103 ustypemap.data.initializeis roughly 2/3 of the observedJNIEnvInit.InitializebudgetThis should be tracked separately from the broader trimmable typemap runtime performance work because it points at the generated managed typemap initialization path itself, not just app activation or steady-state lookup cost.
Subtask of #10788.
10x trimmable data
From 10 Release/CoreCLR/trimmable launches of
samples/HelloWorld:TotalTimemsWaitTimemsjnienv.initializeustypemap.data.initializeus10x LLVM-IR comparison data
After extending the same OTEL instrumentation to the existing LLVM-IR/CoreCLR typemap path, 10 Release/CoreCLR/LLVM-IR launches show:
TotalTimemsWaitTimemsjnienv.initializeustypemap.llvm.activationustypemap.llvm.lookup_jni_name.uncachedusPaired comparison
The directly paired startup boundary is
jnienv.initialize. Trimmable is slower by about 60.6 ms median, andtypemap.data.initializeaccounts for about 62.1 ms median. That means the measured trimmable startup delta is almost entirely explained by generated typemap data initialization.TotalTimeWaitTimejnienv.initializePaired / analogous spans
jnienv.initializejnienv.initializetypemap.data.initializetypemap.initializetypemap.register_native_methodstypemap.peer.createtypemap.llvm.activationtypemap.lookup.java_objecttypemap.llvm.activation.peek_object+ activation subspanspeek_object; 986.5 us full activationtypemap.lookup.jni_nametypemap.llvm.lookup.jni_nametypemap.lookup.jni_name.uncachedtypemap.llvm.lookup.jni_name.uncachedtypemap.lookup.managed_typeclr_typemap_managed_to_java) and should be instrumented separately if needed.typemap.lookup.managed_type.uncachedtypemap.on_register_nativesInterpretation
The lookup and activation paths are not where the big delta is:
The large difference is trimmable-only startup work:
typemap.data.initialize: 62.1 ms mediantypemap.initialize: 4.25 ms medianThose two values line up with the observed
JNIEnvInit.Initializedelta vs LLVM-IR.Raw data
The raw local capture is in
trimmable-typemap-otel-data.mdon draft PR #11502.Local artifacts used while preparing the issue:
Each run directory contains
am-start.txt, host timing, logcat, and Aspire trace/span JSON snapshots.Related work that may change the results
typemap.data.initializeduringJNIEnvInit.Initialize.Acceptance criteria
typemap.data.initialize.JNIEnvInit.Initializespent intypemap.data.initialize, or document why the current cost is expected.