perf(prompts): the button prompts in ~20 s, not ~160 s, with the same files #358
No reviewers
Labels
No labels
area/accessibility
area/audio
area/input
area/install
area/menu
area/renderer
area/saves
area/upscaling
good first issue
gpu/amd
gpu/igpu
gpu/intel
gpu/nvidia
help wanted
kind
bug
kind
chore
kind
docs
kind
feature
kind
performance
kind
question
needs measurements
platform/linux
platform/steam-deck
platform/windows
preview
priority
critical
priority
high
priority
low
status
blocked
status
confirmed
status
duplicate
status
invalid
status
needs-info
status
wontfix
testing wanted
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot!358
Loading…
Reference in a new issue
No description provided.
Delete branch "madebyjordan/Longshot:perf/prompts"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
On Windows, drawing the button prompts for the other controllers took about 170 s of every packaged build's finish stage. With this change they take about 30 s and write the same files.
What changed
read_zs()innx2/prompt_assets.pydecompresses a frame that states its size in one call, into a buffer of that size. A frame without a stated size is read as a stream. Main'sdecompressobj().decompress()grew its output a piece at a time: on Windows that was 81 s of CPU for the 244 MBCommon.bntx, against 0.55 s now. Linux'sreallochides it.guide_route()widens the lines that stay (a 9x9 max filter over the whole texture) once per image, not once per routed line (_WIDENED).generate()draws each face's textures in a process of its own (face_jobs(),draw_face()).Common.bntx.LONGSHOT_PROMPT_JOBSoverrides it.--dumpstill draws in one process.docs/development.md, theLONGSHOT_PROMPT_JOBSrow.tests/test_prompt_speed.py(game-free) checks:read_zsgives main's bytes for frames with and without a stated size;face_jobs' count.gab9281's #314 (open) keeps unchanged prompts between packaged builds. The two go together: #314 skips the drawing when nothing changed, and this makes the drawing itself faster when it runs, such as on the first build and after an update. Both change
nx2/prompt_assets.pyin different functions; whichever merges second rebases.Flags and settings
LONGSHOT_PROMPT_JOBS=<n>1draws them one after another as beforeMeasurements
main:
cf605c85(2026-11-14)this PR: perf/prompts @
74f81d8dHardware: Ryzen 5 5600 (6 cores, 12 threads), 16 GB DDR4 at 2133 MT/s, NVMe, Windows 11
Scene: none (the build). nightly-34's romfs,
nx2/prompt_assets.py --romfs <romfs> --out <empty folder>asmake_game.pyruns it for a packaged build, with the builder's Python 3.13.Method: main and this PR alternated, main / PR / main / PR, each into an empty folder. Wall time is the process's. Every output file was compared by SHA-256 between main and this PR, and between main's two runs.
How to reproduce: the command above on each checkout, alternated.
cf605c8574f81d8dExternal.bfotfExternal.bfotfonly (15 of 16 identical)An earlier run on the same PC at
dd02c6cc(2026-11-13): main 170.6 / 169.6 s, this change 33.2 / 26.7 s, 15 of 16 files byte-identical. The 16th,External.bfotf, also differs between two runs of main.Testing
Tested:
tests/test_prompt_speed.py, and the other prompt checks:test_prompt_guide_lines,test_prompt_skip,test_prompt_auto_face,test_prompt_font_bind,test_appimage_prompt_fonts,test_prompts_live.python -I -B tests/run_all.py --jobs 4on main (483 passed, 6 failed, 70 skipped) and on this PR merged with the other four build PRs of this batch (486 passed, 6 failed (the same 6 as main), 70 skipped).Not tested:
External.bfotf, which differs between main's own runs. So the prompts the game shows are the same./proc/meminfo).Needs other testers:
Screenshots
Nothing on screen: the prompts are the same files.
Risk and rollback
Common.bntxand its images. The count allows one per GB available, andLONGSHOT_PROMPT_JOBS=1draws in one process as before.Reviewer notes
External.bfotfdiffers between two runs of main as well (nondeterministic before this PR); it isn't something this PR changed.Checklist
For everyone
type(scope): description).main.python -I -B tests/run_all.pyrun and passing (any failure that also fails onmainis named above).third_party/untouched (a new folder with aPROVENANCE.mdinstead).If applicable
Assisted-by:/Co-Authored-By:trailers.tests/that reads changed source updated in this PR, not weakened.WIP: perf(prompts): the button prompts in ~20 s, not ~160 s, with the same filesto perf(prompts): the button prompts in ~20 s, not ~160 s, with the same filesRead head
74f81d8dagainst maincf605c85, the complete diff and description, the empty comments/reviews, the drawing and runtime consumers, and the diff and existing review of #314; ran the new speed check and five affected checks, including the C font fixture with GCC and Clang, plus the new check against main's module. No game or build was run.What's good
host/prompts.c; no face is lost at that boundary.--dumpremains serial.Must change
No patch-introduced functional defect found.
How this fits with pull request 314
The two changes do different jobs: 314 avoids generation on an unchanged packaged build; this change speeds generation after a cache miss, including a first build. The cache hashes
prompt_assets.py, so installing this implementation also invalidates an older stamp once. A later cache hit returns before the new process pool is reached.I checked the merge, not just the shared filename. This head merges cleanly with main
cf605c85. Combining it with 314 at6c16f8damergesnx2/prompt_assets.py,nx2/make_game.pyanddocs/development.mdwithout a text conflict. The only conflict is 314's insertion intodocs/tested-configurations.md, which already conflicts with main without this PR. Either code change can land first; the second should retain both paths and rerun the prompt checks.The existing review of 314 remains applicable at its unchanged head: its measured builds still need separate files under
docs/tested/, its Windows request should not promise a fixed finish time on another PC, and its test summary should distinguish passes from skips. Those are not new defects in 358.Measurement and smaller points
docs/tested/. The description does not supply those details or name the six failures from its combined five-PR suite.tests/test_prompt_speed.py, lines 47–77, checks route equality and cache contents, but would also pass if the max filter were recomputed on every call while repopulating the cache. Counting filter calls would protect the intended saving. The driver never exercisesgenerate()ordraw_face(); a serial-versus-spawn fixture would cover worker dispatch, distinct output paths and failure propagation without a game.External.bfotfdiffering between main's own runs explains why a plain hash comparison cannot settle that file, but does not identify its differences. Comparing the decoded font tables with only the identified volatile fields excluded would support the stronger claim that its displayed glyphs are unchanged.Not checked
No actual prompt generation from game assets, packaged Linux build, Windows execution, Steam Deck, controller or in-game visual check here. I checked the published arithmetic, not the underlying logs, hashes or machine load, and did not run the combined 314/358 tree or the full suite. The Linux request remains useful for the new spawn path and its memory use. The source-check jobs are blocked, not passing: https://git.magicbean.dev/MagicBeanDev/Longshot/actions/runs/4280.