Warm a fence's highlighting like a parse, and page the restore by rows
Two things the measurements for the previous commit turned up. Highlighting a fence cost 174ms for a two-hundred-line Kotlin block, and the lazy list charged it again every time that block scrolled back into composition -- six times in one bench run, with the scroll's draw phase at 1.29ms per frame. So it is warmed and cached where parses already are: `highlight` is a plain function taking no colour from the theme, `warm` fills `ParsedReplies.highlighted` from `fences(parse)` off the drawing thread, and `fenceContent` extracts the code here rather than through the library's composable, so the string warmed is the string drawn. And the anchor restore asked for a span counted in events, which goes negative when the anchor's row is the oldest half-row and was coerced to one -- a request per delta, six hundred round trips walking one reply back a word at a time with the spinner up. It asks for a page of rows now. Clean pairs, fresh sessions each side, same gestures. Fence scroll (transcript-bench.sh): draw phase 0.74ms per frame before highlighting existed, 0.77ms after, no lexing in the window either side. Streaming forty linked items (stream-bench.sh): 2412ms of reparsing before, 674ms after; mean 5.0ms to 1.4ms, worst 8.9ms to 7.9ms. Bullet glyphs, fence colours, the image links and the reference link checked on the emulator; lint clean on AGP 9.4.0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6892dc7caf
commit
ab6a797941
6 files changed
+344
-148
No files matched your search
+41
-5
@@ -38,17 +38,53 @@ if [ -z "$keep" ]; then
|
||||
sleep 3
|
||||
fi
|
||||
|
||||
# Pinned to the newest end before anything is sent. The transcript never
|
||||
# moves under a reader who is further back (see TranscriptList), so a reply
|
||||
# streaming into a session parked at an older row arrives entirely
|
||||
# off-screen: nothing recomposes, nothing draws, and the report comes back
|
||||
# with two recompositions in it and no streaming counters at all. That
|
||||
# reads exactly like a build where the work vanished. The control is the
|
||||
# app's own "Jump to latest", which is only there while the newest message
|
||||
# is off screen -- so when it is absent the list is already where it needs
|
||||
# to be.
|
||||
jump=$(ui-trace record -d 1200 -o /tmp/bench-jump.txt >/dev/null 2>&1
|
||||
ui-trace show /tmp/bench-jump.txt -m 'Jump to latest' --field box |
|
||||
grep -o '[0-9]*,[0-9]*\.\.[0-9]*,[0-9]*' | tail -1)
|
||||
if [ -n "$jump" ]; then
|
||||
x=$(echo "$jump" | awk -F'[,.]' '{print int(($1 + $4) / 2)}')
|
||||
y=$(echo "$jump" | awk -F'[,.]' '{print int(($2 + $5) / 2)}')
|
||||
ui-trace record -d 1500 --do "tap $x $y" -o /tmp/bench-tolatest.txt >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
# The first tap resets the report's window; see transcript-bench.sh.
|
||||
ui-trace record -d 2000 --do 'tap 723 205' -o /tmp/bench-reset.txt >/dev/null 2>&1
|
||||
adb logcat -c
|
||||
|
||||
./ui-sandbox.sh send "$sid" "@$file" >/dev/null
|
||||
# Until the echo has finished: its status goes back to idle.
|
||||
|
||||
# Until the reply has finished, measured by the transcript rather than by
|
||||
# the status. A session is idle at both ends of a turn, and polling for
|
||||
# "idle" answers on the first poll -- before the turn has even started --
|
||||
# so the report then covers the moment between the send and the first
|
||||
# delta, and prints a window with nothing in it. The event count only
|
||||
# grows, so "it stopped growing" is the one signal that cannot be true
|
||||
# before the work begins.
|
||||
events() {
|
||||
./ui-sandbox.sh api "/sessions/$sid/transcript?limit=1" |
|
||||
python3 -c 'import json,sys; d=json.load(sys.stdin); print(d[-1]["seq"] if d else 0)'
|
||||
}
|
||||
last=""
|
||||
still=0
|
||||
i=0
|
||||
while [ "$i" -lt 120 ]; do
|
||||
status=$(./ui-sandbox.sh api "/sessions/$sid" |
|
||||
python3 -c 'import json,sys; print(json.load(sys.stdin)["status"])')
|
||||
[ "$status" = idle ] && break
|
||||
while [ "$i" -lt 180 ]; do
|
||||
now=$(events)
|
||||
if [ "$now" = "$last" ]; then
|
||||
still=$((still + 1))
|
||||
[ "$still" -ge 2 ] && break
|
||||
else
|
||||
still=0
|
||||
fi
|
||||
last=$now
|
||||
sleep 2
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
Reference in new issue
Block a user