Uh oh!
There was an error while loading. Please reload this page.
[tests] Add Android interop benchmarks and reduce JNI overhead - #12644
Conversation
Add trimmable typemap, peer activation, JNI roundtrip, Android API, and array marshalling benchmarks. Avoid transient JNI array type-name allocations and redundant class lookups discovered by the new coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
It modifies core JNIEnv interop array-class/type-compat logic in addition to adding benchmarks, making the blast radius broad enough to warrant final human review.
Review tier: Lite
Findings: 1
New issues introduced by this change (1)
| Severity | Finding |
|---|---|
tests/Android.Benchmarks/AndroidArrayMarshallingBenchmarks.cs — 💡 suggestion Operational implications — This benchmark uses Android 12 / API 31 types (e.g.,… |
What changed in this PR
This PR extends the tests/Android.Benchmarks project with targeted BenchmarkDotNet scenarios for common interop and framework usage patterns, and makes a small runtime-side optimization in JNIEnv to reduce transient allocations during array-class lookups (notably for built-in primitive/boxed array signatures).
Changes:
- Add new BenchmarkDotNet benchmark types covering typemap lookups, peer activation/cache behavior, raw JNI roundtrips, object creation, and array marshalling.
- Decompose URI parsing into separate “bound” vs “raw JNI” vs “activation from prepared JNI handles” benchmarks to isolate allocation sources.
- Optimize
JNIEnvarray type compatibility checks and class lookup paths by using UTF-8 literals for built-in array class names and a fast-path for jagged array converter selection.
| File | Description |
|---|---|
| tests/Android.Benchmarks/UriParseAllocationBenchmarks.cs | Adds URI parse benchmarks isolating string creation, raw JNI call, and managed peer activation allocations. |
| tests/Android.Benchmarks/TypeMapLookupBenchmarks.cs | Adds benchmarks for typemap type ↔ signature resolution (framework/app/missing). |
| tests/Android.Benchmarks/PeerLookupBenchmarks.cs | Adds benchmarks for GetObject<T> peer cache hit/miss and global-ref scenarios. |
| tests/Android.Benchmarks/PeerActivationComponentBenchmarks.cs | Adds microbenchmarks for common activation components (class lookup/name/hash/global ref). |
| tests/Android.Benchmarks/ExportRoundtripBenchmarks.cs | Adds JNI→managed exported method roundtrip benchmarks (primitive + string). |
| tests/Android.Benchmarks/AndroidObjectCreationBenchmarks.cs | Adds benchmarks for common framework object creation APIs (Intent, Bitmap, etc.). |
| tests/Android.Benchmarks/AndroidArrayMarshallingBenchmarks.cs | Adds API 31+ array marshalling benchmarks (AppSearch, Parcel, Base64, digest, prepared JNI arrays). |
| tests/Android.Benchmarks/AndroidApiBenchmarks.cs | Adds benchmarks for frequently-used Android API calls (Bundle, resources, system services, view ops). |
| tests/Android.Benchmarks/Android.Benchmarks.csproj | Forces CoreCLR (UseMonoRuntime=false) and trimmable typemap for the benchmarks app. |
| src/Mono.Android/Android.Runtime/JNIEnv.cs | Reduces array-signature allocations via UTF-8 built-in array class names and adjusts array converter selection/compat checks. |
Uh oh!
There was an error while loading. Please reload this page.
Resolve sealed framework peer proxies from the requested managed type and validate them with IsInstanceOf, avoiding runtime Java class-name materialization. Add component benchmark and sealed/generic activation coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers
commented
Sep 2, 2026
/review |
✅ Android PR Reviewer completed successfully!
|
There was a problem hiding this comment.
Reviewed the runtime array-class/compatibility changes, the sealed framework-peer fast path, and the added tests and benchmarks. I found no additional actionable code issues beyond the existing API 31 benchmark-execution comment.
CI build #1579150 is still in progress and currently red: Package Tests macOS > Tests > APKs 1 has failed, with eight lanes still running. The Azure CLI could not initialize its configuration in this environment, so I could not verify the failure's root cause and am not attributing it to this change.
Generated by Android PR Reviewer for #12644 · gpt56 · 199.8 AIC · ⌖ 8.83 AIC · ⊞ 25.7K
Comment /review to run again
Pass the nested array's element type into GetArray so primitive array items are not mistaken for jagged object arrays. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Uh oh!
There was an error while loading. Please reload this page.

Summary
Uri.Parse()into Java execution, string creation, and managed peer activationIsInstanceOf()for Java-to-managed validationSamsung S23 results
byte[256]conversionbyte[256][]conversionThe remaining allocations are exactly the required managed array representations: 280 B for
byte[256], and 1,176 B for the outer array plus four inner arrays. The raw JNI URI controls now allocate 0 B.For sealed framework peer activation, the existing runtime class discovery components cost 471.8 ns and 112 B (
GetObjectClassplusGetJniTypeName). Validating the already-known target class directly costs 384.9 ns and 0 B, removing the class-name allocation and reducing this lookup stage by about 18%.Validation
Mono.Androidwith the sealed-peer optimization