Rust's `encode_rooms` returned a dict per room, which Python then
JSON-encoded again. On the bench's range expansion those two steps were
17 of Rust's 31 ms under the GIL.
`encode_rooms` now returns the rooms as one `bytes` value of JSON object
members and encodes them with the GIL released. The servlet encodes the
rest of the response on a thread, as `respond_with_json` did, splices
Rust's rooms into the rooms object next to any Python fallback rooms, and
sends the body with `respond_with_json_bytes`.
The bench counts the encoder's time as off the GIL. Rust's reactor time
on the range expansion goes from 0.13 of Python's to 0.06.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L51DoxB8VnH8UjXJFDgpNG