Android Performance
Finding
The Android application migration candidate passes on the audited Pixel 9 Pro Fold. Three independent, non-debuggable release AndroidX Microbenchmark invocations ran 30 measurements each against the exact packaged boundary used by the application migration. The authored SDK facade is faster than the released Kotlin/Bouncy Castle implementation for every matched median and p95.
The 64-KiB migration result has substantial margin:
- encryption is 27.55% faster at the median and 43.07% faster at p95; and
- decryption is 29.54% faster at the median and 52.06% faster at p95.
The gate requires at most 1.25x legacy latency. The audited Pixel therefore passes with margin, but one additional production Android device is still required before the two-device gate closes.
Audit identity
| Field | Value |
|---|---|
| Date | 2026-07-27 |
| Device class | Pixel 9 Pro Fold |
| OS | Android API 37, userdebug device build |
| Benchmark target | non-debuggable release AndroidX Benchmark |
| Architecture | arm64 |
| Semantic AAR source | 27e135eac626951507bdeb623d7c56cf6fe88216 |
| Benchmark harness | 4a2989372af41e43d40c793f8674997336c83a58 |
| Legacy Android baseline | a5edacccee3d62757a08dadeceeb3d29a4f4eac6 |
| Independent invocations | 3, with 30 measurements each |
| Configuration | compilation mode speed, profiling disabled |
Legacy and SDK measurements ran as deterministic adjacent pairs to limit ordering and thermal bias. Values below are the median of the three run medians; p95 is the median of the three run p95 values. Negative deltas mean the SDK is faster.
Released implementation comparison
| Operation | Legacy median ns | SDK median ns | Median delta | Legacy p95 ns | SDK p95 ns | p95 delta |
|---|---|---|---|---|---|---|
| Import identity | 124,375 | 86,495 | -30.46% | 187,016 | 185,094 | -1.03% |
| NIP-44 encrypt, 32 B | 208,897 | 60,070 | -71.24% | 338,285 | 60,760 | -82.04% |
| NIP-44 decrypt, 32 B | 206,388 | 58,397 | -71.71% | 306,491 | 58,850 | -80.80% |
| NIP-44 encrypt, 1,024 B | 223,635 | 69,465 | -68.94% | 272,370 | 89,512 | -67.14% |
| NIP-44 decrypt, 1,024 B | 342,755 | 85,990 | -74.91% | 528,429 | 87,162 | -83.51% |
| NIP-44 encrypt, 64,000 B | 1,263,063 | 915,071 | -27.55% | 2,492,802 | 1,419,039 | -43.07% |
| NIP-44 decrypt, 64,000 B | 1,180,058 | 831,496 | -29.54% | 2,638,078 | 1,264,750 | -52.06% |
| Sign NIP-01 event | 596,576 | 250,899 | -57.94% | 896,739 | 265,611 | -70.38% |
| Parse and verify NIP-01 event | 491,143 | 195,887 | -60.12% | 681,859 | 214,374 | -68.56% |
| Create durable NIP-59 gift wrap | 2,067,755 | 729,211 | -64.73% | 3,264,869 | 770,049 | -76.41% |
| Authenticate and unwrap NIP-59 | 1,758,557 | 497,447 | -71.71% | 4,297,929 | 526,557 | -87.75% |
Every SDK median and p95 is faster than its paired legacy measurement. Attachment streaming, which has no legacy equivalent, measured 1,247,319 ns at the median, 1,337,767 ns at p95, and 668 allocations for 64,000 bytes.
One invocation triggered AndroidX Benchmark's automatic 90-second thermal recovery. All 30 measurements then completed, but the cross-run variation confirms that these values remain descriptive until unchanged-revision and production-device calibration is complete.
Layer isolation
The 64-KiB measurements identify where time is spent:
| Layer | Encrypt median ns | Decrypt median ns | Purpose |
|---|---|---|---|
| Native Rust | 552,598 | 540,325 | Crypto and Rust allocation floor |
| Generic string FFI round trip | 950,105 | n/a | Echoes a 64-KiB string across UniFFI/JNA |
| Generic string FFI consume/produce | 641,840 consume | 303,735 produce | Isolates one-way conversion cost |
| Authored JNI facade | 915,071 | 831,496 | Public SDK call with byte-array bridge |
| Released Kotlin | 1,263,063 | 1,180,058 | Adjacent migration baseline |
The earlier regression was boundary cost, not the native cipher. The authored Android path now sends UTF-8 byte arrays through a narrow JNI bridge and constructs the Kotlin value once, while generic UniFFI remains the portable JVM path. Absolute values moved with device state between audits, which is why the decision uses paired SDK/legacy results from the same invocation.
Allocation result
AndroidX allocation medians also favor the authored facade:
| Operation | Legacy allocations | SDK allocations | Delta |
|---|---|---|---|
| Import identity | 1,785.0 | 201.9 | -88.69% |
| NIP-44 encrypt, 32 B | 2,594.0 | 7.0 | -99.73% |
| NIP-44 decrypt, 32 B | 2,581.0 | 5.0 | -99.81% |
| NIP-44 encrypt, 64,000 B | 2,594.1 | 7.0 | -99.73% |
| NIP-44 decrypt, 64,000 B | 2,582.0 | 6.0 | -99.77% |
| Sign NIP-01 event | 5,415.0 | 384.6 | -92.90% |
| Parse and verify event | 4,292.0 | 374.5 | -91.27% |
| Create gift wrap | 16,245.8 | 499.0 | -96.93% |
| Unwrap | 13,881.0 | 358.0 | -97.42% |
These are benchmark allocation counts, not heap-retention or PSS measurements.
Developer guidance
- Import one
SoftchatIdentityper signed-in session and retain its cachedpublicKey. - Run crypto, event verification, wrapping, and large parsing away from the Android main thread.
- Use the authored
com.softcose.softchat.protocolAPI. Do not call the JNI bridge or generated UniFFI package directly. - Pass complete bounded messages. Repeated small FFI calls lose the advantage of the coarse facade.
- Keep Room, WorkManager, HTTP, sockets, and file lifecycle in the Android layer. Persist a delivery intent before sending it through a relay session.
- Ship the release AAR with its consumer rules and symbols. The verified
package contains
arm64-v8aandx86_64libraries with 16-KiB page alignment and passes an R8-minified external consumer.
Remaining Android work
- Reproduce median and p95 on one additional production-build device.
- Isolate SDK and legacy PSS, startup, energy, and sustained thermal behavior.
- Calibrate five unchanged-revision runs before turning descriptive numbers into automatic device-class gates.
- Exercise Room persistence, process death, migration, quarantine, resume, and rollback through an application integration.
Run the complete build, install, three-run collection, and sanitized aggregate with the commands in the Performance Benchmarks source guide.