Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

perf(editor): dedupe alignment snap-lines in O(n) instead of O(n2)#692

Open
ly-wang19 wants to merge 1 commit into
THU-MAIC:main from
ly-wang19:perf/uniq-align-lines-map
Open

perf(editor): dedupe alignment snap-lines in O(n) instead of O(n2) #692
ly-wang19 wants to merge 1 commit into
THU-MAIC:main from
ly-wang19:perf/uniq-align-lines-map

Conversation

@ly-wang19

@ly-wang19 ly-wang19 commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

What & why

uniqAlignLines (lib/utils/element.ts) merges alignment snap-lines with Array.findIndex inside a forEachO(n2):

lines.forEach((line) => {
 const index = uniqLines.findIndex((_line) => _line.value === line.value); // O(n)
 ...
});

It runs on every drag/scale mousemove (useDragElement / useScaleElement), and the snap-line count grows with the number of nearby element edges. On element-dense canvases that’s ~n2 comparisons per pointer move at ~60 Hz → drag jank.

Closes #691.

Fix

Dedupe in O(n) via a Map keyed on value. A Map preserves first-occurrence insertion order (re-set-ting an existing key keeps its slot), so the output order and the range-merge semantics are unchanged — behavior-preserving, just linear.

Test plan

New tests/utils/uniq-align-lines.test.ts (5 cases): dedupe + outer-bound range merge, first-occurrence order preserved, single line, empty input, and many-duplicates collapse. tsc/prettier/eslint clean.

No user-facing strings (no i18n impact). (Separate test file from element.test.ts to avoid overlap with #675, which also touches element.ts.)

uniqAlignLines used Array.findIndex inside a forEach (O(n^2)) to merge
alignment snap-lines. It runs on every drag/scale mousemove and the line
count scales with nearby element edges, so it janks on element-dense
canvases. Dedupe via a Map keyed on value (O(n)); a Map preserves
first-occurrence order, so output order and range-merge semantics are
unchanged.
Closes THU-MAIC#691 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

uniqAlignLines is O(n2) (findIndex in a loop) on the drag/scale hot path

1 participant

AltStyle によって変換されたページ (->オリジナル) /