Skip to content

Make proof-tree painting cheap on large proofs #3863

Merged
unp1 merged 2 commits into
mainfrom
prooftree-render-perf
Jun 26, 2026
Merged

Make proof-tree painting cheap on large proofs #3863
unp1 merged 2 commits into
mainfrom
prooftree-render-perf

Conversation

@unp1

@unp1 unp1 commented Jun 26, 2026

Copy link
Copy Markdown
Member

Intended Change

ProofTreeView.ProofRenderer.renderBranch decides the rare "linked-folder" icon by running a
breadth-first search over the branch's entire subtree on every repaint, calling the
linear-scan Proof.getOpenGoal on each visited node. That is O(subtree × open goals) per open branch,
per paint no matter whether the merge rule is used or not. On large proofs (tens of thousands of nodes, many open goals) this turns tree painting
into billions of operations and freezes the EDT. A thread dump on a ~300k-node proof showed the
EDT RUNNABLE with 70+s of CPU in renderBranch.

The fix iterates the proof's open goals instead of the whole subtree (far fewer of them),
short-circuited by the cheap isLinked() test and walking ancestors only for linked goals. A
branch is still marked linked iff it contains a linked open goal — same result, a tiny fraction of
the cost. renderLeaf additionally skips the getOpenGoal scan for closed leaves (a closed leaf
has no open goal). Behaviour is unchanged; only the cost of computing the icon changes, and large
proof trees now paint smoothly.

Type of pull request

  • Bug fix (non-breaking change which fixes an issue)
  • There are changes to the (Java) code

Ensuring quality

  • I made sure that introduced/changed code is well documented (javadoc and inline comments).
  • I have tested the feature as follows: the change is behaviour-preserving (the linked-folder icon
    still appears for branches that contain a linked goal); on a >300k-node proof the tree now paints
    smoothly instead of freezing the GUI.
  • I have checked that runtime performance has not deteriorated (it is a performance improvement).

Additional information and contact(s)

Found via a thread dump while working on the multi-core prover branch (#3842), which makes such
large proofs easy to reach, but the fix is stock-KeY and independent of it — factored out here as a
standalone change.

PR created with AI tooling

The contributions within this pull request are licensed under GPLv2 (only) for inclusion in KeY.

unp1 and others added 2 commits June 26, 2026 12:28
A thread dump on a ~300k-node proof showed the EDT RUNNABLE with 70+s of CPU in
ProofRenderer.renderBranch: for every OPEN branch node, on every repaint, it ran a
breadth-first search over the branch's whole subtree and called the linear-scan
Proof.getOpenGoal on each visited node -- O(subtree x openGoals) per branch, per
paint -- purely to decide the rare linked-folder icon. On a large proof with many
open goals that is billions of operations per paint, which is the GUI sluggishness.

Replace it with a scan over the proof's open goals (far fewer than a big subtree),
short-circuited by the cheap isLinked() pre-check, walking ancestors only for the
linked ones. Equivalent result, no caching/staleness. Also skip the getOpenGoal
scan for closed leaves in renderLeaf (a closed leaf has no open goal).

This is stock-KeY behaviour, exposed now that MT makes such large proofs reachable.
@unp1 unp1 enabled auto-merge June 26, 2026 10:34
@unp1 unp1 self-assigned this Jun 26, 2026
@unp1 unp1 added this to the v3.0.0 milestone Jun 26, 2026
@unp1 unp1 changed the title Make proof-tree painting cheap on large proofs (linked-goal icon) Make proof-tree painting cheap on large proofs Jun 26, 2026

@Drodt Drodt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@unp1 unp1 added this pull request to the merge queue Jun 26, 2026
Merged via the queue into main with commit 25fed6e Jun 26, 2026
36 checks passed
@unp1 unp1 deleted the prooftree-render-perf branch June 26, 2026 12:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants