Repository navigation
perf: Nitro V1 with optimized result encoding - #468
Draft
chrispader wants to merge 22 commits into
Draft
chrispader wants to merge 22 commits into
chrispader wants to merge 22 commits into
Conversation
Co-authored-by: Codex <[email protected]>
The example only used react-native-quick-crypto and @craftzdog/react-native-buffer to provide a global Buffer. The buffer package covers that without native code and drops a Nitro 0.x module that can't build against Nitro V1. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Rewrite the Nitro specs as decorated classes, regenerate the bindings, and port the C++ hybrid objects to V1's value-type Promise, ArrayBuffer and Callback APIs. JavaScript imports the hybrid classes from the specs, which re-export the runtime modules that nitrogen generates under Nitro V1 doesn't support CocoaPods, so the iOS, macOS and native lockfile jobs are paused. The Nitro 0.37 patch moves into the macOS example because the root install can't apply it to Nitro V1. BREAKING CHANGE: Requires React Native 0.88 and Nitro V1. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: Codex <[email protected]>
The podspec loads CocoaPods files that nitrogen V1 no longer generates, so the test can't run until iOS builds with Swift Package Manager. Co-Authored-By: Claude Opus 5.5 <[email protected]>
The package's react-native and source fields pointed at src, so apps compiled the decorated .nitro.ts specs with their own Babel config, which React Native's default preset can't parse. The entry points now point at lib, and bob parses the specs through per-target Babel configs. main points at the CommonJS build that bob validates it against, and CI builds the package so a broken build shows up before a release. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Nitro V1 only builds iOS through Swift Package Manager. Package.swift manifests now build the library and sqlite-vec. The library reads the app's nitroSQLite settings like the podspec did and adds iosSqliteFlags for custom SQLite definitions, and sqlite-vec registers itself when SwiftPM links it. The podspecs remain so React Native CLI can discover the packages. The example app moves to Swift Package Manager with patched manifests for react-native-screens and the clipboard module, and iOS CI resumes on Xcode 27. BREAKING CHANGE: iOS apps must build with Swift Package Manager and Xcode with Swift 6.4 or newer. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Update the installation steps, the iOS configuration page and the encryption guide for Nitro V1 and Swift Package Manager, including the nitroSQLite.iosSqliteFlags setting and the manifest cache that applies package.json changes only after it's cleared. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Nitro V1 registers hybrid objects under the module's namespace, so NitroSQLitePreparedStatement no longer needs its prefix to stay unique. The spec, its C++ implementation and the generated bindings now use PreparedStatement. The public NitroSQLitePreparedStatement type keeps its name because the JavaScript API already exports a PreparedStatement interface. Co-Authored-By: Claude Opus 5.5 <[email protected]>
The shorter class name changes how clang-format wraps the constructor and sorts the generated spec includes. Co-Authored-By: Claude Opus 5.5 <[email protected]>
A PlatformContext hybrid object now returns the database, temporary and legacy database directories. Kotlin reads them from the Android application context, and Objective-C++ applies the iOS Info.plist options that OnLoad.mm handled at launch. JavaScript passes them to the NitroSQLite constructor, so each root resolves databases against its own directories instead of static paths, and the Android JNI setter and the iOS +load hook go away. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: Codex <[email protected]>
Co-authored-by: Codex <[email protected]>
Encode rows during SQLite reads and preserve native values where JSON cannot represent them. Co-authored-by: Codex <[email protected]>
REAL columns often store whole numbers. Formatting them as 64-bit integers is about twice as fast as std::to_chars for doubles and about five times as fast as SQLite's formatter, which Apple builds use. It also drops the ".0" that SQLite's formatter appends. Negative zero keeps the double path so it stays -0. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Apple's libc++ marks floating-point std::to_chars unavailable below iOS 16.3, so Apple builds formatted every fractional REAL value with SQLite's formatter, which takes about twice as long. Look the function up at runtime instead and keep SQLite's formatter only on systems that don't ship it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Every result went through JSON.parse, including the empty result of each write and single-row lookups. That parse has a fixed cost per batch, which made prepared point lookups 4 to 11% slower than direct JSI conversion on Android devices. A batch now keeps native values up to 32 cells and switches to JSON once it grows past that, encoding the rows it has read so far. Streamed batches also reuse the previous batch's JSON size as their capacity. The result tests now check each edge case with one row and with 40 rows, so both conversion paths stay covered. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Asynchronous calls copied their parameters to own them on the worker thread, then copied them again into the queued operation. executeBatchAsync copied every batch command twice more to replace JS-backed ArrayBuffers. The owned copies are now moved into the operations, and batch commands replace their ArrayBuffers in place, so each parameter is copied once. Co-Authored-By: Claude Opus 5.5 <[email protected]>
The read benchmarks only measured synchronous queries, where native code encodes and JavaScript parses results on the same thread. They also stored only whole numbers in REAL columns, which skip the slower number formatting. Add asynchronous versions of the narrow and wide reads and a read of 100k rows with fractional REAL values. The existing cases keep their order and labels so earlier results stay comparable. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Describe each optimization in this branch, the benchmark it targets, and the stack PR it should move into after benchmarking. Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Port the app workload cases from #470: a chat app that stores synced messages, browses its inbox and conversations, and launches, plus key-value storage, a JSON response cache, a BLOB thumbnail cache, async point lookups, and synchronous inserts in one transaction. The Drizzle and executeRaw cases stay out because this branch has neither API yet. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This branch had an error being deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Nitro V1 stack was slower than
mainin some device benchmarks, mostly because of the AnyJSON result encoding from #467. Apple builds format REAL values with SQLite's slower number formatter, and every result pays for a JSON parse, including empty and single-row results.This PR combines the whole stack with fixes for both, two smaller optimizations, and benchmark cases for asynchronous reads and fractional numbers, so everything can be measured in one build.
V1_OPTIMIZATIONS.mdlists each change and the stack PR it belongs to.🤖 Generated with Claude Code