mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 05:50:35 +00:00
A profile of the benchmark worlds showed where a sync spends its time. - The token sync of shapes that apply no tokens took 38% of a sync in the 1000-copy world: for every synced shape, generate-update-tokens walked every sync attribute, resolved its group and its token attributes, and only then found that neither the main shape nor the copy applies a token. It now returns at once, and the token attributes of each sync attribute are computed once, at load. - A sync looks through every object of each page and component to find the copies it updates, so in a file with many shapes and few copies the search costs more than the sync itself. The new benchmark world main-edit-among-many-shapes syncs a main edit into 10 copies in a page with 20,000 plain rects; its baseline, measured before the change below, joins the recorded one with a note, and its result joins the golden master. generate-sync-container called the uses-assets? multimethod on every object through a lazy filter; the predicate is now chosen once per container (asset-user?) and the objects walked with reduce-kv into a vector, in the same order. - compare-children searched the remaining children (d/seek) for every child out of place, and dropped a child taken out of order with a lazy remove, so a reorder took quadratic time and nested one lazy sequence per child taken. It now looks children up by their reference or id (index-positions) and skips those taken out of order when the walk reaches them, with the same callbacks in the same order. The sync of a reorder stays slow: when a main with 1,000 children moves its first one to the end, each copy still gets 999 moves (F85), and applying them is what costs (4.75 s to 4.26 s for 10 copies). Fewer moves change what a sync writes, so that waits for Phase 4c. No behavior change: the golden masters and the suites are unchanged. Benchmark (lower quantile, ms; baseline / now / ratio): deepest-edit-through-three-levels 35.2 / 18.6 / 0.53 edit-through-a-chain-of-dependents 68.9 / 36.4 / 0.53 library-update-into-copies 83.1 / 43.0 / 0.52 main-edit-among-many-shapes 4.8 / 2.3 / 0.48 main-edit-into-10-copies 1.8 / 0.9 / 0.48 main-edit-into-100-copies 15.4 / 8.4 / 0.54 main-edit-into-1000-copies 153.1 / 90.1 / 0.59 variant-switch-into-copies 32.1 / 20.0 / 0.63 (main-edit-among-many-shapes: baseline measured before the search change.) AI-assisted-by: claude-opus-5-5
28 lines
1.0 KiB
Clojure
28 lines
1.0 KiB
Clojure
;; Component sync benchmark baseline, written by `scripts/bench-components record`.
|
|
{:commit "1e6615a132",
|
|
:date "2026-10-09",
|
|
:machine
|
|
{:cpu "Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz",
|
|
:cores 12,
|
|
:os "Linux amd64",
|
|
:jvm "26.0.2"},
|
|
:results
|
|
{:deepest-edit-through-three-levels
|
|
{:mean-ms 36.343, :lower-q-ms 35.215, :passes 4},
|
|
:edit-through-a-chain-of-dependents
|
|
{:mean-ms 75.119, :lower-q-ms 68.931, :passes 3},
|
|
:library-update-into-copies
|
|
{:mean-ms 89.295, :lower-q-ms 83.083, :passes 1},
|
|
;; added in Phase 3 (2026-10-14), measured on the code before the object
|
|
;; scan of a sync changed, on the same machine
|
|
:main-edit-among-many-shapes
|
|
{:mean-ms 5.465, :lower-q-ms 4.837, :passes 1},
|
|
:main-edit-into-10-copies
|
|
{:mean-ms 1.847, :lower-q-ms 1.79, :passes 1},
|
|
:main-edit-into-100-copies
|
|
{:mean-ms 16.234, :lower-q-ms 15.415, :passes 1},
|
|
:main-edit-into-1000-copies
|
|
{:mean-ms 158.728, :lower-q-ms 153.086, :passes 1},
|
|
:variant-switch-into-copies
|
|
{:mean-ms 33.1, :lower-q-ms 32.052, :passes 1}}}
|