Repository navigation
Conversation
Quest-Claim: 4893fda2ef922f8a
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…enchmark Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pends Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

Finishes quest/m1/ffi-export/bench.md.
Problem
The repo had no committed measurement of rust2-ffi's bindings.
just ffi benchprinted ad hoc timings and saved nothing, so the epic's rule that every generator "is measured, with its generated size" had no baseline. The speed work, along with checks-raise and swift-noncopyable, had nothing to measure against.Approach
ffi/moq/bench/export.{c,cpp,kt,py,swift,go,dart}now time one set of cases, mapped onto BoltFFI's table. A newexport.rstimes the same cases as the Rust floor, on the stand-in's API. The cases: handle call, u64 getter, record return, object return, frame write (plain and stamped), ready read, woken read, payload, and write-plus-read throughput at 100 B to 1 MiB. Each case reports wall time and process CPU time.just ffi bench=bench-build+bench-run [rounds].bench-runrecords the 1-minute load average over each program run intotarget/bench/raw.tsv. Thenbench/ffi/report.pyprints the median of each case beside its median load, plus the sizes of the generated bindings, their Rust glue, and the native libraries (raw, gzip, and stripped). The nightly job's summary gets the same tables.bench/ffi/README.mdcommits the numbers and the analysis: which costs a call spends, ranked by what they cost moq's frame path; a per-handle baseline for checks-raise and swift-noncopyable; and a comparison with the BoltFFI targets. The quest file is deleted, and the links to it now point at the README.Loaded host: at the maintainer's direction this was measured through plain
quest gate, not--host. The 1-minute load average stayed between 22 and 29 on 24 threads for the whole run. Each cell shows its load and is the median of 5 rounds, and the README marks the numbers as taken on a loaded host. Use the CPU tables first. Large-frame throughput (16 KiB and up) is bandwidth-bound and moved 2x between runs, so the README tells readers to use only the 100 B and 1 KiB rows.Headline numbers (CPU ns, median):
Timestamphandle per frameChoices made without asking:
perf_event_openin each of 8 languages. CPU time counts every thread, so it includes the JVM's JIT/GC threads and Swift's executor workers (documented).ensure_future, an undispatched coroutine). It therefore includes starting a task, as the README says.just ffi benchdepends onmoq-exportnow, not on the wholejust ffi moqtest run.Impact
just ffi benchgainsbench-buildandbench-run [rounds], and writesffi/target/bench/report.md.ffi-benchjob is renamed "Bench the bindings".Alternatives
quest gate --host(dropped at the maintainer's direction; it starved other agents).perf statinstruction counts: more stable under load, but each language would need its own per-case counter bindings. Not worth the cost while CPU time already separates the costs by 2x or more.Follow-ups
Recommended to plan with
/quest-plan, from the ranking in the README:Copytypes cross by value.TimestampisCopyin Rust but exports as a handle, which costs 92 to 256 ns per frame in Kotlin, Python, Go, and Dart (this doubles the write in Go and Dart). Export aCopy,Drop-free type with private fields as an opaque value copied across, not anArchandle.runtime.AddCleanupandNativeFinalizerregistration on every frame, group, and future returned.Already planned: checks-raise and swift-noncopyable. The README's per-handle baseline section gives them the u64-getter and handle-call rows to measure against.
Decisions
Both decisions were taken unattended on 2026-11-10 by the coordinating agent while the maintainer was away. They follow this PR's recommendations; confirm them when you merge.
/quest-planplans follow-ups 1 to 4 when the PR merges, and 5 and 6 stay dropped. Rejected: creating the quests here, as the quest's Goal wording suggested, which the quest guide reserves for/quest-plan.Models
Size: M
Implementer: Claude Code, Opus 5.5, medium effort
🤖 Generated with Claude Code
(Written by Opus 5.5 with medium)
Review
Rewritten by
quest reviewafter each round.01a1c761-dbe6-7fc3-ab54-dbedce961a18, round 1The expanded benchmark needs two macOS portability fixes before the supported Darwin workflow can produce a report.ffi/justfile:100:Read load averages through a platform-aware interfacebench/ffi/report.py:57:Select native library filenames for the host platform