5.1 KiB
Small architecture diagram CPU investigation
Question: does core projection/routing explain issue 44's low FPS with roughly eight architecture cards? This experiment narrows that question; it neither reproduces native frame rate nor establishes a complete cause.
Workload and source
The screenshot uses names from examples/release1. Its exact model, projection,
camera and authored geometry are unavailable. The probe loads the unchanged
examples/release1/model.json, measures its five saved views, and constructs a
clearly labeled eight-card SA Overview approximation using those semantic
elements. Approximate coordinates and stable placement IDs are in the probe;
it has 8 projected nodes, 6 ports and 13 projected edges. It is not a recovered
copy of the user's diagram. All data changes occur in memory.
Source: 24b1eab07d306d8cb091bb46f7daf9f027a8f1c0; core, manifest and lockfile
are unchanged from the drag contribution's 1a669130 production source.
Windows 10.0.26200, Rust 1.98.1, x86_64-pc-windows-gnullvm, LLVM-MinGW
20260908 UCRT, reported CPU Intel Core i7-10870H with 4 exposed cores/threads.
The probe was optimized with -O and linked to the existing unoptimized
development-profile core library used by the completed desktop test build.
This distinction matters: optimizing the driver does not optimize that library.
The desktop test process had completed before measurement; no Cargo compilation
was started until after measurement. Other operating-system workloads were not
controlled, so outliers are retained rather than interpreted as stable capacity.
Method and results
Each phase gets 3 warmups and 40 timed samples, with returned values passed to
black_box. Reported p50/p95 select sorted index ceil((n-1)*p) as implemented
in the source. Returned output destruction is outside each timed phase. Diagram
movement uses a deterministic small delta sequence and the existing descendant
and authored-route translation APIs. Index creation, projection, routing, and
combined movement preparation are measured separately. The probe does not model
allocation transaction admission or an Iced frame.
For the eight-card approximation, performance-01.log records:
| Phase | p50 ms | p95 ms | max ms |
|---|---|---|---|
| Reused-index projection | 0.3885 | 0.7550 | 1.2965 |
| Fresh-index projection | 1.7135 | 2.7022 | 4.2204 |
| Settled routing | 2.4525 | 4.4617 | 4.7735 |
| Moved routing | 3.1907 | 4.4781 | 4.5672 |
| Movement preparation + projection + routing | 4.2640 | 6.8259 | 8.8052 |
This workload does not expose severe core latency sufficient by itself to explain very low FPS. It does not rule out different authored routes, allocation admission, hardware/rendering, or the user's exact scene. Repeated fresh-index projection has a measurable cost, but no change is justified solely by this small sample. No FPS or performance-fix claim follows.
Source observations and next discriminating measurement
Independent read-only hot-path review found that DiagramCanvas::scene already
caches projection and routing by semantic context and transient geometry.
Ordinary node movement changes preview geometry and routes the full view;
route gestures use route_edge_preview. Ordinary hover need not reroute.
diagram/port_labels.rs requests redraw on every mouse event, including when
no tooltip is visible. DiagramCanvas::draw rebuilds geometry and each dot-grid
circle on every draw. At a 1900x660 canvas this yields about 2,240 circles at
zoom 1 and 6,528 at minimum spacing. Scene caching does not cache that geometry.
views.rs also performs an unindexed project_view during app view rebuilding;
legacy node-motion redraw does not itself require that full UI rebuild.
Next, measure actual canvas draw/frame costs independently for idle hover, pan, ordinary node drag and allocation drag, with grid generation separated from node/edge/text rendering and frame presentation. Compare the same scene/camera and renderer before changing production code. Native automation was stopped with Escape; no GPU/frame measurement was attempted in this experiment. Live ownership and subsequent results belong to issue 44.
Reproduction
Build oa-core at the identified source with the stated Windows toolchain, then
compile this standalone probe against that exact library and matching dependency
directory. For a fresh standard Cargo development build:
cargo build --locked -p oa-core
rustc --edition=2024 -O harness/experiments/architecture-perf-20260925/architecture_perf_probe.rs --extern oa_core=target/debug/liboa_core.rlib -L dependency=target/debug/deps -C linker=clang.exe -o architecture_perf_probe.exe
./architecture_perf_probe.exe examples/release1/model.json 40
The actual run linked target/debug/deps/liboa_core-2f3c5174cb6398fd.rlib
and used the same dependency directory. Set the linker/runtime PATH as required
by the Windows toolchain. Compiler flags, core profile, machine load and fixture
all affect timings; preserve them when comparing candidates. This standalone
probe is experimental evidence, not a production dependency or a timing test.