Skip to content

BridgeJS: Optimize numeric array transfer with bulk TypedArray copy#745

Merged
kateinoigakukun merged 1 commit into
mainfrom
krodak/typed-array
May 13, 2026
Merged

BridgeJS: Optimize numeric array transfer with bulk TypedArray copy#745
kateinoigakukun merged 1 commit into
mainfrom
krodak/typed-array

Conversation

@krodak
Copy link
Copy Markdown
Member

@krodak krodak commented May 13, 2026

Overview

Optimize numeric array transfer by using bulk TypedArray memory copy instead of element-by-element stack serialization. When a Swift function passes or receives a numeric array ([Int], [UInt8], [Float], [Double], etc.), BridgeJS now transfers the data as a single bulk operation. TypeScript types remain number[] / bigint[] — no user-facing API change.

This is a transparent performance optimization following the same pattern as bridgeJSStackPopAsOptional — a specialized ABI for numeric element types without changing the type contract. Non-numeric arrays ([String], [MyStruct], etc.) continue using the existing element-by-element stack protocol.

1. Swift → JS direction: Array.bridgeJSTypedArrayPush() calls withUnsafeBufferPointer to pass (ptr, count, kind) to a new swift_js_push_typed_array WASM import, which copies the bytes into a JS TypedArray. A pre-allocated for-loop then converts to number[] for the caller.

2. JS → Swift direction: [T].bridgeJSTypedArrayLiftParameter(sourceId, count) receives a retained TypedArray from JS, allocates via Array(unsafeUninitializedCapacity:), and calls back to JS via swift_js_init_typed_array_memory to bulk copy — the same retain-allocate-callback pattern used by string lowering.

3. Affected types: All integer types (Int8 through Int64, signed and unsigned), Float, Double, plus pointer-width Int/UInt. A new _BridgeJSTypedArrayElement protocol marks eligible types. BridgeType.isNumericScalar and typedArrayKind on the skeleton side route the codegen.

Benchmark results

Release build, 10K iterations × 5 runs:

Test Before After Speedup
takeIntArray (1K, JS→Swift) 758 ms 13 ms 58×
takeDoubleArray (1K, JS→Swift) 791 ms 13 ms 61×
makeIntArray (1K, Swift→JS) 221 ms 18 ms 12×
makeIntArrayLarge (10K, Swift→JS) 2160 ms 146 ms 15×
roundtripIntArray (1K) 964 ms 29 ms 33×
takeStringArray (non-numeric) 23 ms 25 ms unchanged

@krodak krodak requested a review from kateinoigakukun May 13, 2026 09:09
@krodak krodak self-assigned this May 13, 2026
@krodak krodak force-pushed the krodak/typed-array branch from 16d3b1e to 785e1e2 Compare May 13, 2026 10:21
@krodak krodak requested a review from MaxDesiatov May 13, 2026 10:31
Comment thread Plugins/BridgeJS/Sources/BridgeJSCore/ClosureCodegen.swift Outdated
@krodak krodak force-pushed the krodak/typed-array branch 3 times, most recently from 937dadc to 8cb4535 Compare May 13, 2026 18:57
@krodak krodak force-pushed the krodak/typed-array branch from 8cb4535 to 2e74754 Compare May 13, 2026 19:10
@kateinoigakukun kateinoigakukun merged commit 403ae95 into main May 13, 2026
13 checks passed
@kateinoigakukun kateinoigakukun deleted the krodak/typed-array branch May 13, 2026 20:58
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.

2 participants