Skip to content

JSON mapping: codecs, creators, generics, arrays and null semantics - #6105

Merged
shai-almog merged 5 commits into
masterfrom
json-codec-extensibility
Oct 25, 2026
Merged

shai-almog merged 5 commits into
masterfrom
json-codec-extensibility

Conversation

@shai-almog

Copy link
Copy Markdown
Collaborator

Fixes #5995.

Both the backend's build-time JSON codecs (BackendJsonCodecs) and the client's @Mapped mappers (MappingAnnotationProcessor) now read one shared set of annotations, so a class shared by an app and its backend has one JSON contract.

New

  • @JsonAdapter + JsonTypeAdapter<T>: application codecs, called directly with no reflection, and validated at build time (public, concrete, no-arg constructor, T matching the field).
  • @JsonCreator: immutable DTOs through a constructor or a static factory; records also work.
  • Typed generic DTOs (Page<User> gets its own codec) and one-dimensional arrays. Shapes that stay unsupported (multi-dimensional arrays, bad adapters, folding codec names) fail the build with the field's name.
  • @JsonStrict refuses unknown members. @JsonProperty gains aliases and required. @JsonOmitNull; @JsonFormat(STRING/NUMBER) for dates (ISO-8601 UTC) and numbers.
  • Path diagnostics such as $.items[2].id: required member is missing. The depth limit is configurable through cn1.json.maxDepth.

Compatibility

  • A class that uses none of the new options reads and writes as before.
  • On the client, an explicit null clears a field only in @JsonStrict classes, on required members, and through adapters. Elsewhere it is read like an absent member, as the parser has always done.
  • Tests that asserted "arrays are refused" now assert that int[][] is refused.

Docs: Backend-Web.asciidoc gains "Shaping the JSON contract" and a "Coming from Jackson" migration table, and Annotation-JSON-XML-Mapping.asciidoc is updated to match.

Verification

  • build-engine suite: 2884 tests, 0 failures. SpotBugs reports 0 findings on build-engine, backend and core-unittests, and the cast-semantics check passes.
  • Three rounds of adversarial review fixed the following:
    • alias diagnostics;
    • ISO date validation (Feb 30, 24:30, offset range);
    • the adapter null contract between client and server;
    • array element range and type checks on the client;
    • a client explicit-null behaviour change for unannotated classes.

🤖 Generated with Claude Code

…5995)

Extends both the backend's build-time JSON codecs and the client's @mapped
mappers with one shared set of annotations:

- @JsonAdapter / JsonTypeAdapter: application codecs, called directly, no
  reflection; validated at build time.
- @jsoncreator: immutable DTOs built through a constructor or factory.
- Typed generic DTOs (Page<User> gets its own codec) and one-dimensional
  arrays; shapes that stay unsupported fail the build by name.
- @JsonStrict (unknown members refused), @JsonProperty aliases/required,
  @JsonOmitNull, @jsonformat(STRING/NUMBER) for dates and numbers.
- Path diagnostics ($.items[2].id: required member is missing) and a
  configurable depth limit (cn1.json.maxDepth).

Default behaviour is unchanged: a class that uses none of the new options
reads and writes as before, including an explicit null on the client.
Docs gain a "Shaping the JSON contract" section and a Jackson migration
table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Cloudflare Preview

shai-almog and others added 3 commits October 25, 2026 16:42
…ned adapter example

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s null

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Flutter vs Codename One

Same application, built both ways: Flutter's AOT compile of the gallery, and the identical Dart source transpiled to Java on Codename One. Lower is better for every metric, so a ratio above 1.00x means Codename One is ahead by that factor.

android

9 interleaved rounds; host load 0.27, 1.47, 1.24

Metric Codename One Flutter Ratio Winner
Installed size 78.2 MB 95.8 MB 1.22x Codename One
Executable code 4.7 MB 20.6 MB 4.42x Codename One
Download size (zipped) 78.2 MB 95.8 MB 1.22x Codename One
Cold start to first frame on screen 374 ms 1328 ms 3.60x Codename One
Memory at rest 44.4 MB 77.0 MB 1.73x Codename One

Start-up and memory at rest are judged round by round: the ratio is the median of the per-round ratios, each from two launches made back to back, and the times and sizes shown are each side's median, so the ratio need not equal their quotient. Codename One was ahead in 9 of 9 rounds on cold start to first frame on screen; 9 of 9 rounds on memory at rest.

Compute -- the VM workloads (vm/benchmarks), run inside each app; time is the best of the app's own repetitions, higher ratio means Codename One is faster.

Workload Codename One Flutter Ratio
intArithmetic 56 ms 119 ms 2.12x
longArithmetic 34 ms 36 ms 1.06x
mathTranscendental 160 ms 197 ms 1.23x
arraySequential 16 ms 21 ms 1.31x
arrayRandom 195 ms 214 ms 1.10x
objectAllocation 65 ms 25 ms 0.39x
valueEscape 6 ms 5 ms 0.83x
hashMapChurn 126 ms 197 ms 1.56x
stringBuilding 58 ms 79 ms 1.36x
recursion 42 ms 177 ms 4.21x
quicksortBench 104 ms 120 ms 1.15x
Geometric mean 1.26x

Gate: within tolerance against scripts/flutter-bench/baseline.

Android sizes are for the arm64-v8a slice a phone is delivered, on both sides; Flutter's release apk carries three ABIs and would otherwise count its engine about three times.
Android start-up and memory come from an x86_64 emulator with a software GPU. They compare the two runtimes on one machine; they are not phone timings, and a renderer that leans on the GPU is penalised more there.
This platform's adapter has not been exercised end to end before; treat the first published run as the thing under review.

ios

9 interleaved rounds; host load 31.42, 31.25, 24.74

Metric Codename One Flutter Ratio Winner
Installed size 108.1 MB 110.5 MB 1.02x Codename One
Executable code 17.1 MB 19.1 MB 1.11x Codename One
Download size (zipped) 80.0 MB 81.9 MB 1.02x Codename One
Cold start to first frame on screen -- -- -- not measured
Memory at rest -- -- -- not measured

Compute -- the VM workloads (vm/benchmarks), run inside each app; time is the best of the app's own repetitions, higher ratio means Codename One is faster.

Not measured: iOS compute is not measured: a device build needs signed hardware, and on the simulator Flutter runs its JIT debug engine rather than AOT code. The macOS row runs the same ParparVM and Dart AOT compilers on the same Apple silicon.

Gate: within tolerance against scripts/flutter-bench/baseline. Smaller than its baseline, which does not fail the gate: Executable code -7.50% -- rebaseline to tighten. To accept the move, download this platform's baseline-<platform>.json artifact and run python3 scripts/flutter-bench/flutter_baseline.py calibrate --pr 6105 --reason "<why these moved>" baseline-ios.json, then commit the overlay it writes.

iOS start-up and memory are not measured here: Flutter cannot AOT-compile for the simulator, so a simulator run would time a JIT debug build against a release build. Sizes come from release device bundles; timings need signed hardware.
This platform's adapter has not been exercised end to end before; treat the first published run as the thing under review.

javascript

9 interleaved rounds; host load 2.07, 1.24, 0.53

Metric Codename One Flutter Ratio Winner
Installed size 103.9 MB 122.5 MB 1.18x Codename One
Executable code 12.9 MB 25.2 MB 1.96x Codename One
Download size (zipped) 76.3 MB 84.1 MB 1.10x Codename One
Cold start to first frame on screen -- -- -- not measured
Memory at rest -- -- -- not measured

Compute -- the VM workloads (vm/benchmarks), run inside each app; time is the best of the app's own repetitions, higher ratio means Codename One is faster.

Workload Codename One Flutter Ratio
intArithmetic 656 ms wrong result Flutter: wrong result
longArithmetic 5077 ms did not run Flutter: did not run
mathTranscendental 570 ms did not run Flutter: did not run
arraySequential 228 ms 82 ms 0.36x
arrayRandom 935 ms wrong result Flutter: wrong result
objectAllocation 38 ms 27 ms 0.71x
valueEscape 154 ms 7 ms 0.04x
hashMapChurn 994 ms 249 ms 0.25x
stringBuilding 518 ms 107 ms 0.21x
recursion 508 ms 489 ms 0.96x
quicksortBench 399 ms wrong result Flutter: wrong result
Geometric mean 0.29x

Gate: within tolerance against scripts/flutter-bench/baseline; BEHIND FLUTTER on Compute (geomean of the VM workloads) (reported, not gated: a loss to Flutter on the web is currently accepted).

the JavaScript adapter needs a Chrome DevTools driver; sizes are reported and timings are not
This platform's adapter has not been exercised end to end before; treat the first published run as the thing under review.

linux

9 interleaved rounds; host load 0.23, 2.88, 2.5

Metric Codename One Flutter Ratio Winner
Installed size 111.4 MB 143.8 MB 1.29x Codename One
Executable code 14.1 MB 16.1 MB 1.15x Codename One
Download size (zipped) 80.9 MB 92.9 MB 1.15x Codename One
Cold start to first frame on screen 146 ms 211 ms 1.45x Codename One
Memory at rest 85.6 MB 226.0 MB 2.63x Codename One

Start-up and memory at rest are judged round by round: the ratio is the median of the per-round ratios, each from two launches made back to back, and the times and sizes shown are each side's median, so the ratio need not equal their quotient. Codename One was ahead in 9 of 9 rounds on cold start to first frame on screen; 9 of 9 rounds on memory at rest.

Compute -- the VM workloads (vm/benchmarks), run inside each app; time is the best of the app's own repetitions, higher ratio means Codename One is faster.

Workload Codename One Flutter Ratio
intArithmetic 89 ms 242 ms 2.72x
longArithmetic 60 ms 65 ms 1.08x
mathTranscendental 205 ms 212 ms 1.03x
arraySequential 17 ms 42 ms 2.47x
arrayRandom 263 ms 301 ms 1.14x
objectAllocation 34 ms 39 ms 1.15x
valueEscape 5 ms 13 ms 2.60x
hashMapChurn 48 ms 300 ms 6.25x
stringBuilding 32 ms 119 ms 3.72x
recursion 110 ms 241 ms 2.19x
quicksortBench 173 ms 167 ms 0.96x
Geometric mean 1.91x

Gate: within tolerance against scripts/flutter-bench/baseline.

This platform's adapter has not been exercised end to end before; treat the first published run as the thing under review.

macos

9 interleaved rounds; host load 3.92, 13.92, 16.98

Metric Codename One Flutter Ratio Winner
Installed size 124.1 MB 139.4 MB 1.12x Codename One
Executable code 33.0 MB 47.9 MB 1.45x Codename One
Download size (zipped) 85.5 MB 93.3 MB 1.09x Codename One
Cold start to first frame on screen 495 ms 590 ms 1.26x Codename One
Memory at rest 36.7 MB 53.1 MB 1.45x Codename One

Start-up and memory at rest are judged round by round: the ratio is the median of the per-round ratios, each from two launches made back to back, and the times and sizes shown are each side's median, so the ratio need not equal their quotient. Codename One was ahead in 6 of 9 rounds on cold start to first frame on screen; 9 of 9 rounds on memory at rest.

Compute -- the VM workloads (vm/benchmarks), run inside each app; time is the best of the app's own repetitions, higher ratio means Codename One is faster.

Workload Codename One Flutter Ratio
intArithmetic 121 ms 254 ms 2.10x
longArithmetic 80 ms 76 ms 0.95x
mathTranscendental 288 ms 353 ms 1.23x
arraySequential 11 ms 47 ms 4.27x
arrayRandom 288 ms 313 ms 1.09x
objectAllocation 72 ms 28 ms 0.39x
valueEscape 6 ms 15 ms 2.50x
hashMapChurn 39 ms 195 ms 5.00x
stringBuilding 23 ms 117 ms 5.09x
recursion 135 ms 285 ms 2.11x
quicksortBench 120 ms 134 ms 1.12x
Geometric mean 1.80x

Gate: within tolerance against scripts/flutter-bench/baseline. Smaller than its baseline, which does not fail the gate: Executable code -6.57% -- rebaseline to tighten. To accept the move, download this platform's baseline-<platform>.json artifact and run python3 scripts/flutter-bench/flutter_baseline.py calibrate --pr 6105 --reason "<why these moved>" baseline-macos.json, then commit the overlay it writes.

This platform's adapter has not been exercised end to end before; treat the first published run as the thing under review.

windows

9 interleaved rounds

Metric Codename One Flutter Ratio Winner
Installed size 107.8 MB 121.1 MB 1.12x Codename One
Executable code 11.3 MB 14.1 MB 1.25x Codename One
Download size (zipped) 77.8 MB 86.4 MB 1.11x Codename One
Cold start to first frame on screen 158 ms 247 ms 1.52x Codename One
Memory at rest 58.4 MB 92.5 MB 1.58x Codename One

Start-up and memory at rest are judged round by round: the ratio is the median of the per-round ratios, each from two launches made back to back, and the times and sizes shown are each side's median, so the ratio need not equal their quotient. Codename One was ahead in 9 of 9 rounds on cold start to first frame on screen; 9 of 9 rounds on memory at rest.

Compute -- the VM workloads (vm/benchmarks), run inside each app; time is the best of the app's own repetitions, higher ratio means Codename One is faster.

Workload Codename One Flutter Ratio
intArithmetic 90 ms 241 ms 2.68x
longArithmetic 58 ms 65 ms 1.12x
mathTranscendental 192 ms 211 ms 1.10x
arraySequential 12 ms 44 ms 3.67x
arrayRandom 276 ms 330 ms 1.20x
objectAllocation 37 ms 44 ms 1.19x
valueEscape 1 ms 13 ms 13.00x
hashMapChurn 47 ms 283 ms 6.02x
stringBuilding 29 ms 118 ms 4.07x
recursion 216 ms 238 ms 1.10x
quicksortBench 170 ms 164 ms 0.96x
Geometric mean 2.20x

Gate: within tolerance against scripts/flutter-bench/baseline. Smaller than its baseline, which does not fail the gate: Executable code -10.80%; Download size (zipped) -0.78% -- rebaseline to tighten. To accept the move, download this platform's baseline-<platform>.json artifact and run python3 scripts/flutter-bench/flutter_baseline.py calibrate --pr 6105 --reason "<why these moved>" baseline-windows.json, then commit the overlay it writes.

This platform's adapter has not been exercised end to end before; treat the first published run as the thing under review.

Codename One wins 26 of 26 measured metrics across 6 platform(s).

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Developer Guide build artifacts are available for download from this workflow run:

Developer Guide quality checks:

  • AsciiDoc linter: No issues found (report)
  • Vale: No alerts found (report)
  • Paragraph capitalization: No paragraph capitalization issues (report)
  • LanguageTool: No grammar matches (report)
  • Image references: No unused images detected (report)

@shai-almog

shai-almog commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 191 screenshots: 191 matched.

Native Android coverage

  • 📊 Line coverage: 18.90% (48250/255341 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 17.64% (229182/1299035), branch 12.04% (16817/139675), complexity 9.67% (12910/133466), method 14.57% (9122/62628), class 25.16% (1774/7052)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6367 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.ClassReader – 0.00% (0/1524 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.MethodWriter – 0.00% (0/922 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/736 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • okio.okio.Buffer – 0.00% (0/687 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/625 lines covered)
      • com.codename1.androidcompat.rt.com.codename1.androidcompat.rt.TextXmlPullParser – 0.00% (0/623 lines covered)
      • com.codename1.androidcompat.androidx.constraintlayout.core.widgets.com.codename1.androidcompat.androidx.constraintlayout.core.widgets.Flow – 0.00% (0/576 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 18.90% (48250/255341 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 17.64% (229182/1299035), branch 12.04% (16817/139675), complexity 9.67% (12910/133466), method 14.57% (9122/62628), class 25.16% (1774/7052)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6367 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.ClassReader – 0.00% (0/1524 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.MethodWriter – 0.00% (0/922 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/736 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • okio.okio.Buffer – 0.00% (0/687 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/625 lines covered)
      • com.codename1.androidcompat.rt.com.codename1.androidcompat.rt.TextXmlPullParser – 0.00% (0/623 lines covered)
      • com.codename1.androidcompat.androidx.constraintlayout.core.widgets.com.codename1.androidcompat.androidx.constraintlayout.core.widgets.Flow – 0.00% (0/576 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend scalar fallback (no native SIMD)
SIMD int-add (64K x300) java 177ms / native 122ms = 1.4x speedup
SIMD float-mul (64K x300) java 50ms / native 83ms = 0.6x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 58.000 ms
Base64 CN1 decode 52.000 ms
Base64 native encode 286.000 ms
Base64 encode ratio (CN1/native) 0.203x (79.7% faster)
Base64 native decode 157.000 ms
Base64 decode ratio (CN1/native) 0.331x (66.9% faster)
Image encode benchmark status skipped (SIMD unsupported)

@shai-almog

shai-almog commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 227 screenshots: 227 matched.
✅ JavaScript-port screenshot tests passed.

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ✅ ByteCodeTranslator: 0 findings (no issues)
    • ✅ android: 0 findings (no issues)
    • ✅ android-compat: 0 findings (no issues)
    • ✅ android-res-compiler: 0 findings (no issues)
    • ✅ backend: 0 findings (no issues)
    • ✅ backend-test: 0 findings (no issues)
    • ✅ build-engine: 0 findings (no issues)
    • ✅ build-hint-catalog: 0 findings (no issues)
    • ✅ build-hint-tools: 0 findings (no issues)
    • ✅ codenameone-gradle-plugin: 0 findings (no issues)
    • ✅ codenameone-maven-plugin: 0 findings (no issues)
    • ✅ core-unittests: 0 findings (no issues)
    • ✅ desktop-compat-runtime: 0 findings (no issues)
    • ✅ fxml-compiler: 0 findings (no issues)
    • ✅ ios: 0 findings (no issues)
    • ✅ javac: 0 findings (no issues)
    • ✅ javafx-compat: 0 findings (no issues)
    • ✅ project-model: 0 findings (no issues)
    • ✅ swing-compat: 0 findings (no issues)
  • ✅ PMD: 0 findings (no issues) [Report archive]
  • ✅ Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

@shai-almog

shai-almog commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 206 screenshots: 206 matched.
Native Windows port, REAL shipping pipeline: the hellocodenameone screenshot suite rendered by a binary CROSS-COMPILED on Linux (clang-cl + xwin, WebView2 linked) and RUN on a Windows x64 runner. Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 56ms / native 6ms = 9.3x speedup
SIMD float-mul (64K x300) java 56ms / native 5ms = 11.2x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 75.000 ms
Base64 CN1 decode 90.000 ms
Base64 SIMD encode 113.000 ms
Base64 encode ratio (SIMD/CN1) 1.507x (50.7% slower)
Base64 SIMD decode 104.000 ms
Base64 decode ratio (SIMD/CN1) 1.156x (15.6% slower)
Image encode benchmark iterations 100
Image createMask (SIMD off) 9.000 ms
Image createMask (SIMD on) 3.000 ms
Image createMask ratio (SIMD on/off) 0.333x (66.7% faster)
Image applyMask (SIMD off) 25.000 ms
Image applyMask (SIMD on) 27.000 ms
Image applyMask ratio (SIMD on/off) 1.080x (8.0% slower)
Image modifyAlpha (SIMD off) 28.000 ms
Image modifyAlpha (SIMD on) 18.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.643x (35.7% faster)
Image modifyAlpha removeColor (SIMD off) 30.000 ms
Image modifyAlpha removeColor (SIMD on) 41.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 1.367x (36.7% slower)

@shai-almog

shai-almog commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 206 screenshots: 206 matched.
Native Windows port (x64 / Intel-AMD): full hellocodenameone screenshot suite rendered offscreen with Direct2D/DirectWrite, plus the real benchmarks (base64 native/CN1/SIMD, image createMask/applyMask/modifyAlpha/PNG/JPEG, SSE2 SIMD kernels). Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 57ms / native 4ms = 14.2x speedup
SIMD float-mul (64K x300) java 57ms / native 4ms = 14.2x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 76.000 ms
Base64 CN1 decode 89.000 ms
Base64 SIMD encode 113.000 ms
Base64 encode ratio (SIMD/CN1) 1.487x (48.7% slower)
Base64 SIMD decode 99.000 ms
Base64 decode ratio (SIMD/CN1) 1.112x (11.2% slower)
Image encode benchmark iterations 100
Image createMask (SIMD off) 10.000 ms
Image createMask (SIMD on) 6.000 ms
Image createMask ratio (SIMD on/off) 0.600x (40.0% faster)
Image applyMask (SIMD off) 40.000 ms
Image applyMask (SIMD on) 39.000 ms
Image applyMask ratio (SIMD on/off) 0.975x (2.5% faster)
Image modifyAlpha (SIMD off) 31.000 ms
Image modifyAlpha (SIMD on) 30.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.968x (3.2% faster)
Image modifyAlpha removeColor (SIMD off) 38.000 ms
Image modifyAlpha removeColor (SIMD on) 17.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.447x (55.3% faster)

ParparVM vs HotSpot (JDK 25): Windows x64

Runner CPU: AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD (baseline windows-x64@amd64-family-25-model-1-authenticamd)

Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in vm/selfhost/perf-baseline/ is a regression and fails; one that far below is an improvement, reported but not failed (a row whose calibration runs were noisier carries a wider tolerance), and for RAM the change must also exceed 0.05x in absolute terms. Both run unpinned on all of the runner's CPUs, with their own default thread counts.

Benchmark Cores Time RAM Status
hello (WinHelloMain) 4 1.50x (base 1.22x, +22.5%) 0.64x (base 0.94x, -32.3%) ok
translator (self) 4 0.79x (base 0.83x, -4.7%) 0.54x (base 0.54x, -1.0%) ok
intArithmetic 4 1.10x (base 1.10x, +0.0%) 0.06x (base 0.06x, +2.6%) ok
longArithmetic 4 1.14x (base 1.08x, +5.0%) 0.06x (base 0.05x, +3.3%) ok
mathTranscendental 4 0.79x (base 0.79x, -0.3%) 0.06x (base 0.06x, +2.9%) ok
arraySequential 4 1.33x (base 1.36x, -2.8%) 0.39x (base 0.39x, +0.3%) ok
arrayRandom 4 1.03x (base 1.06x, -3.2%) 0.23x (base 0.23x, +0.4%) ok
objectAllocation 4 1.61x (base 1.56x, +3.0%) 0.30x (base 0.39x, -22.0%) ok
valueEscape 4 0.10x (base 0.10x, +0.3%) 0.05x (base 0.04x, +3.6%) ok
hashMapChurn 4 1.89x (base 1.80x, +5.3%) 0.09x (base 0.09x, -1.3%) ok
stringBuilding 4 1.23x (base 1.22x, +1.1%) 0.29x (base 0.32x, -10.1%) ok
recursion 4 1.41x (base 1.49x, -5.8%) 0.06x (base 0.06x, +1.5%) ok
quicksort 4 1.11x (base 1.13x, -2.2%) 0.12x (base 0.12x, +0.9%) ok

Result: no regression

@shai-almog

shai-almog commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 206 screenshots: 206 matched.
Native Linux port (x64), GTK3/Cairo/Pango, ParparVM bytecode-to-C (no JVM): the hellocodenameone screenshot suite rendered by a native ELF built + run on the GitHub x64 runner. Baseline: scripts/linux/screenshots.

ParparVM vs HotSpot (JDK 25): Linux x64

Runner CPU: AMD EPYC 7763 64-Core Processor (baseline linux-x64@amd-epyc-7763-64-core-processor)

Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in vm/selfhost/perf-baseline/ is a regression and fails; one that far below is an improvement, reported but not failed (a row whose calibration runs were noisier carries a wider tolerance), and for RAM the change must also exceed 0.05x in absolute terms. Both run unpinned on all of the runner's CPUs, with their own default thread counts.

Benchmark Cores Time RAM Status
hello (LinuxHelloMain) 4 0.88x (base 0.85x, +4.5%) 0.62x (base 0.83x, -26.1%) ok
translator (self) 4 0.55x (base 0.64x, -14.3%) 0.46x (base 0.52x, -10.5%) ok
intArithmetic 4 1.10x (base 1.12x, -1.2%) 0.07x (base 0.06x, +33.6%) ok
longArithmetic 4 1.08x (base 1.08x, +0.0%) 0.06x (base 0.05x, +4.1%) ok
mathTranscendental 4 1.09x (base 1.08x, +0.1%) 0.06x (base 0.07x, -19.6%) ok
arraySequential 4 1.99x (base 2.00x, -0.5%) 0.36x (base 0.36x, -0.4%) ok
arrayRandom 4 0.93x (base 0.91x, +2.4%) 0.23x (base 0.21x, +9.5%) ok
objectAllocation 4 1.52x (base 1.65x, -7.8%) 0.29x (base 0.35x, -16.5%) ok
valueEscape 4 0.10x (base 0.10x, -0.3%) 0.05x (base 0.04x, +4.2%) ok
hashMapChurn 4 1.46x (base 1.48x, -1.4%) 0.09x (base 0.09x, -0.7%) ok
stringBuilding 4 1.45x (base 1.39x, +4.4%) 0.26x (base 0.31x, -16.6%) ok
recursion 4 1.19x (base 1.25x, -5.5%) 0.08x (base 0.08x, +0.7%) ok
quicksort 4 1.10x (base 1.07x, +2.9%) 0.13x (base 0.11x, +15.6%) ok

Result: no regression

@shai-almog

shai-almog commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 206 screenshots: 206 matched.
Native Linux port (arm64), GTK3/Cairo/Pango, ParparVM bytecode-to-C (no JVM): the hellocodenameone screenshot suite rendered by a native ELF built + run on the GitHub arm64 runner. Baseline: scripts/linux/screenshots-arm.

ParparVM vs HotSpot (JDK 25): Linux arm64

Runner CPU: Neoverse-N2 (baseline linux-arm64@neoverse-n2)

Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in vm/selfhost/perf-baseline/ is a regression and fails; one that far below is an improvement, reported but not failed (a row whose calibration runs were noisier carries a wider tolerance), and for RAM the change must also exceed 0.05x in absolute terms. Both run unpinned on all of the runner's CPUs, with their own default thread counts.

Benchmark Cores Time RAM Status
hello (LinuxHelloMain) 4 0.96x (base 1.02x, -5.7%) 0.66x (base 0.93x, -29.4%) ok
translator (self) 4 0.77x (base 0.70x, +10.0%) 0.44x (base 0.43x, +2.8%) ok
intArithmetic 4 1.04x (base 1.04x, -0.0%) 0.03x (base 0.03x, +4.5%) ok
longArithmetic 4 0.79x (base 0.79x, +0.0%) 0.03x (base 0.03x, +4.9%) ok
mathTranscendental 4 1.09x (base 1.10x, -0.3%) 0.04x (base 0.03x, +9.4%) ok
arraySequential 4 0.38x (base 0.36x, +3.8%) 0.37x (base 0.37x, +0.2%) ok
arrayRandom 4 0.94x (base 0.94x, +0.3%) 0.20x (base 0.20x, +0.6%) ok
objectAllocation 4 1.96x (base 1.77x, +10.8%) 0.38x (base 0.37x, +2.8%) ok
valueEscape 4 0.51x (base 0.51x, -0.1%) 0.03x (base 0.03x, +4.9%) ok
hashMapChurn 4 0.84x (base 0.84x, -0.1%) 0.13x (base 0.12x, +4.1%) ok
stringBuilding 4 1.45x (base 1.57x, -7.3%) 0.26x (base 0.26x, +0.1%) ok
recursion 4 1.43x (base 1.43x, -0.6%) 0.04x (base 0.04x, +3.0%) ok
quicksort 4 1.00x (base 0.99x, +1.0%) 0.09x (base 0.09x, +1.2%) ok

Result: no regression

Chain the parse cause, drop a redundant qualified name, end the
number-sniffing loop without a branch, and reword an adverb.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

✅ ByteCodeTranslator Quality Report

Test & Coverage

  • ✅ Tests: 881 total, 0 failed, 55 skipped

Benchmark Results

  • Execution Time: 7240 ms

  • Hotspots (Top 20 sampled methods):

    • 9.47% java.lang.Object.hashCode (101 samples)
    • 7.69% com.codename1.tools.translator.IteratorEscape.ctorOnlyStoresParamsIntoThis (82 samples)
    • 7.22% java.util.ArrayList.indexOf (77 samples)
    • 5.06% java.lang.System.identityHashCode (54 samples)
    • 4.40% com.codename1.tools.translator.BytecodeMethod.equals (47 samples)
    • 2.81% com.codename1.tools.translator.IteratorEscape.mangle (30 samples)
    • 2.72% com.codename1.tools.translator.BytecodeMethod.updateInlinableFieldDependencies (29 samples)
    • 2.72% java.lang.StringBuilder.append (29 samples)
    • 2.44% com.codename1.tools.translator.classfile.analysis.Frame.execute (26 samples)
    • 1.41% com.codename1.tools.translator.ReachabilityCull.run (15 samples)
    • 1.41% java.lang.String.equals (15 samples)
    • 1.41% java.io.FileOutputStream.writeBytes (15 samples)
    • 1.41% com.codename1.tools.translator.bytecodes.Invoke.findMethodUp (15 samples)
    • 1.31% com.codename1.tools.translator.NativeSymbolIndex.<init> (14 samples)
    • 1.31% com.codename1.tools.translator.Parser.cullMethods (14 samples)
    • 1.22% com.codename1.tools.translator.bytecodes.Invoke.resolveDirectTarget (13 samples)
    • 1.22% java.util.HashMap.hash (13 samples)
    • 1.12% com.codename1.tools.translator.BytecodeMethod.addToConstantPool (12 samples)
    • 1.12% java.util.AbstractCollection.containsAll (12 samples)
    • 1.03% com.codename1.tools.translator.JavascriptReachability.enqueueResolved (11 samples)
  • ⚠️ Coverage report not generated.

Static Analysis

  • ✅ SpotBugs: no findings (report was not generated by the build).
  • ⚠️ PMD report not generated.
  • ⚠️ Checkstyle report not generated.

Generated automatically by the PR CI workflow.

@shai-almog

shai-almog commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 206 screenshots: 206 matched.
Native Windows port (arm64 / Apple Silicon - Arm): full hellocodenameone screenshot suite rendered offscreen with Direct2D/DirectWrite, plus the real benchmarks (base64 native/CN1/SIMD, image createMask/applyMask/modifyAlpha/PNG/JPEG, NEON SIMD kernels). Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 53ms / native 2ms = 26.5x speedup
SIMD float-mul (64K x300) java 53ms / native 2ms = 26.5x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 59.000 ms
Base64 CN1 decode 70.000 ms
Base64 SIMD encode 77.000 ms
Base64 encode ratio (SIMD/CN1) 1.305x (30.5% slower)
Base64 SIMD decode 71.000 ms
Base64 decode ratio (SIMD/CN1) 1.014x (1.4% slower)
Image encode benchmark iterations 100
Image createMask (SIMD off) 5.000 ms
Image createMask (SIMD on) 1.000 ms
Image createMask ratio (SIMD on/off) 0.200x (80.0% faster)
Image applyMask (SIMD off) 20.000 ms
Image applyMask (SIMD on) 22.000 ms
Image applyMask ratio (SIMD on/off) 1.100x (10.0% slower)
Image modifyAlpha (SIMD off) 17.000 ms
Image modifyAlpha (SIMD on) 13.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.765x (23.5% faster)
Image modifyAlpha removeColor (SIMD off) 15.000 ms
Image modifyAlpha removeColor (SIMD on) 9.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.600x (40.0% faster)

ParparVM vs HotSpot (JDK 25): Windows arm64

Runner CPU: ARMv8 (64-bit) Family 8 Model D49 Revision 0, MICROSOFT CORPORATION (baseline windows-arm64@armv8-64-bit-family-8-model-d49-microsoft-corporation)

Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in vm/selfhost/perf-baseline/ is a regression and fails; one that far below is an improvement, reported but not failed (a row whose calibration runs were noisier carries a wider tolerance), and for RAM the change must also exceed 0.05x in absolute terms. Both run unpinned on all of the runner's CPUs, with their own default thread counts.

Benchmark Cores Time RAM Status
hello (WinHelloMain) 4 1.02x (base 1.11x, -7.5%) 0.60x (base 0.75x, -20.6%) ok
translator (self) 4 0.85x (base 0.84x, +1.5%) 0.49x (base 0.51x, -2.5%) ok
intArithmetic 4 1.04x (base 1.04x, +0.0%) 0.06x (base 0.06x, +3.1%) ok
longArithmetic 4 0.79x (base 0.80x, -0.1%) 0.06x (base 0.06x, +3.4%) ok
mathTranscendental 4 0.72x (base 0.72x, +0.1%) 0.07x (base 0.06x, +1.7%) ok
arraySequential 4 0.36x (base 0.46x, -19.8%) 0.39x (base 0.39x, +0.0%) ok
arrayRandom 4 0.94x (base 0.94x, +0.4%) 0.23x (base 0.23x, +0.2%) ok
objectAllocation 4 1.78x (base 1.82x, -2.4%) 0.40x (base 0.43x, -6.3%) ok
valueEscape 4 0.76x (base 0.76x, +0.0%) 0.05x (base 0.05x, +3.7%) ok
hashMapChurn 4 1.00x (base 0.98x, +1.3%) 0.12x (base 0.12x, -2.2%) ok
stringBuilding 4 1.61x (base 1.43x, +12.8%) 0.27x (base 0.27x, -0.2%) ok
recursion 4 1.55x (base 1.46x, +5.9%) 0.07x (base 0.07x, +1.3%) ok
quicksort 4 1.00x (base 1.00x, +0.4%) 0.12x (base 0.12x, +0.5%) ok

Result: no regression

@shai-almog
shai-almog merged commit df645f6 into master Oct 25, 2026
114 of 121 checks passed
@shai-almog
shai-almog deleted the json-codec-extensibility branch October 25, 2026 19:19
@shai-almog

shai-almog commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 192 screenshots: 192 matched.
✅ Native Mac screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 741 seconds

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 51ms / native 3ms = 17.0x speedup
SIMD float-mul (64K x300) java 55ms / native 3ms = 18.3x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 58.000 ms
Base64 CN1 decode 55.000 ms
Image encode benchmark iterations 100
Image createMask (SIMD off) 16.000 ms
Image createMask (SIMD on) 10.000 ms
Image createMask ratio (SIMD on/off) 0.625x (37.5% faster)
Image applyMask (SIMD off) 93.000 ms
Image applyMask (SIMD on) 102.000 ms
Image applyMask ratio (SIMD on/off) 1.097x (9.7% slower)
Image modifyAlpha (SIMD off) 98.000 ms
Image modifyAlpha (SIMD on) 98.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.000x (0.0% slower)
Image modifyAlpha removeColor (SIMD off) 78.000 ms
Image modifyAlpha removeColor (SIMD on) 115.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 1.474x (47.4% slower)

ParparVM vs HotSpot (JDK 25): macOS arm64

Runner CPU: Apple M1 (Virtual) (baseline macos-arm64)

Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in vm/selfhost/perf-baseline/ is a regression and fails; one that far below is an improvement, reported but not failed (a row whose calibration runs were noisier carries a wider tolerance), and for RAM the change must also exceed 0.05x in absolute terms. Both run unpinned on all of the runner's CPUs, with their own default thread counts.

Benchmark Cores Time RAM Status
hello (HelloCodenameOne) 3 0.81x (base 0.96x, -15.2%) 0.88x (base 0.93x, -5.3%) ok
translator (self) 3 0.71x (base 0.62x, +13.7%) 0.76x (base 0.78x, -2.9%) ok
intArithmetic 3 1.04x (base 1.03x, +0.5%) 0.12x (base 0.12x, +1.4%) ok
longArithmetic 3 1.01x (base 1.03x, -1.3%) 0.11x (base 0.07x, +60.6%) ok
mathTranscendental 3 0.96x (base 1.01x, -5.0%) 0.12x (base 0.12x, +1.1%) ok
arraySequential 3 0.45x (base 0.42x, +6.0%) 0.53x (base 0.53x, +0.2%) ok
arrayRandom 3 0.93x (base 0.99x, -6.3%) 0.33x (base 0.32x, +0.3%) ok
objectAllocation 3 1.13x (base 1.11x, +2.5%) 0.70x (base 0.72x, -3.2%) ok
valueEscape 3 0.48x (base 0.51x, -4.4%) 0.09x (base 0.09x, -2.1%) ok
hashMapChurn 3 1.09x (base 1.18x, -7.0%) 0.07x (base 0.07x, +7.7%) ok
stringBuilding 3 0.88x (base 0.84x, +4.4%) 0.46x (base 0.46x, -1.5%) ok
recursion 3 1.22x (base 1.24x, -0.8%) 0.12x (base 0.12x, +1.1%) ok
quicksort 3 1.00x (base 1.01x, -0.9%) 0.11x (base 0.11x, +1.2%) ok

Result: no regression

@shai-almog

shai-almog commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 188 screenshots: 188 matched.
✅ Native Mac screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 732 seconds

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 56ms / native 3ms = 18.6x speedup
SIMD float-mul (64K x300) java 59ms / native 3ms = 19.6x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 79.000 ms
Base64 CN1 decode 66.000 ms
Base64 native encode 823.000 ms
Base64 encode ratio (CN1/native) 0.096x (90.4% faster)
Base64 native decode 367.000 ms
Base64 decode ratio (CN1/native) 0.180x (82.0% faster)
Base64 SIMD encode 76.000 ms
Base64 encode ratio (SIMD/CN1) 0.962x (3.8% faster)
Base64 SIMD decode 66.000 ms
Base64 decode ratio (SIMD/CN1) 1.000x (0.0% slower)
Base64 encode ratio (SIMD/native) 0.092x (90.8% faster)
Base64 decode ratio (SIMD/native) 0.180x (82.0% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 28.000 ms
Image createMask (SIMD on) 24.000 ms
Image createMask ratio (SIMD on/off) 0.857x (14.3% faster)
Image applyMask (SIMD off) 116.000 ms
Image applyMask (SIMD on) 86.000 ms
Image applyMask ratio (SIMD on/off) 0.741x (25.9% faster)
Image modifyAlpha (SIMD off) 80.000 ms
Image modifyAlpha (SIMD on) 75.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.938x (6.3% faster)
Image modifyAlpha removeColor (SIMD off) 56.000 ms
Image modifyAlpha removeColor (SIMD on) 50.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.893x (10.7% faster)

@shai-almog

shai-almog commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 189 screenshots: 189 matched.
✅ Native iOS Metal screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 2232 seconds

Build and Run Timing

Metric Duration
Simulator Boot 49000 ms
Simulator Boot (Run) 2000 ms
App Install 29000 ms
App Launch 81000 ms
Test Execution 548000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 311ms / native 3ms = 103.6x speedup
SIMD float-mul (64K x300) java 198ms / native 6ms = 33.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 129.000 ms
Base64 CN1 decode 166.000 ms
Base64 native encode 2309.000 ms
Base64 encode ratio (CN1/native) 0.056x (94.4% faster)
Base64 native decode 1851.000 ms
Base64 decode ratio (CN1/native) 0.090x (91.0% faster)
Base64 SIMD encode 74.000 ms
Base64 encode ratio (SIMD/CN1) 0.574x (42.6% faster)
Base64 SIMD decode 135.000 ms
Base64 decode ratio (SIMD/CN1) 0.813x (18.7% faster)
Base64 encode ratio (SIMD/native) 0.032x (96.8% faster)
Base64 decode ratio (SIMD/native) 0.073x (92.7% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 22.000 ms
Image createMask (SIMD on) 18.000 ms
Image createMask ratio (SIMD on/off) 0.818x (18.2% faster)
Image applyMask (SIMD off) 199.000 ms
Image applyMask (SIMD on) 688.000 ms
Image applyMask ratio (SIMD on/off) 3.457x (245.7% slower)
Image modifyAlpha (SIMD off) 578.000 ms
Image modifyAlpha (SIMD on) 715.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.237x (23.7% slower)
Image modifyAlpha removeColor (SIMD off) 91.000 ms
Image modifyAlpha removeColor (SIMD on) 755.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 8.297x (729.7% slower)

@shai-almog

shai-almog commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 184 screenshots: 184 matched.
✅ Native Apple TV (tvOS, Metal) screenshot tests passed.

@shai-almog

shai-almog commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator Author

Compared 249 screenshots: 249 matched.
✅ Native Apple Watch (watchOS, Core Graphics) screenshot tests passed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RFE: Backend JSON codec extensibility and migration support

1 participant