Skip to content

perf: improve runtime performance of exhaustive search#2214

Open
triceo wants to merge 4 commits intoTimefoldAI:mainfrom
triceo:exhaustive
Open

perf: improve runtime performance of exhaustive search#2214
triceo wants to merge 4 commits intoTimefoldAI:mainfrom
triceo:exhaustive

Conversation

@triceo
Copy link
Copy Markdown
Collaborator

@triceo triceo commented Mar 27, 2026

No description provided.

@triceo triceo requested a review from zepfred as a code owner March 27, 2026 07:26
Copilot AI review requested due to automatic review settings March 27, 2026 07:26
@triceo triceo added this to the v2.0.0 milestone Mar 27, 2026
@triceo triceo self-assigned this Mar 27, 2026
@triceo triceo deployed to internal March 27, 2026 07:26 — with GitHub Actions Active
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR optimizes exhaustive search runtime by reducing per-step allocations and stream overhead, and by simplifying several hot-path code paths involved in node expansion, undo handling, and destination selection.

Changes:

  • Replace stream-based iteration in list destination selection with lightweight iterator implementations (MappingIterator, ConcatenatingIterator).
  • Reduce allocation/copying on the undo hot path by returning an undo Move from the recording score director and resetting the internal change list by reference swap.
  • Micro-optimize exhaustive search internals (comparators, queue operations, remove unused expandable tracking).

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
core/src/main/java/ai/timefold/solver/core/impl/score/director/RevertableScoreDirector.java Replaces copyChanges() with createUndoMove() and updates contract/Javadoc.
core/src/main/java/ai/timefold/solver/core/impl/move/VariableChangeRecordingScoreDirector.java Implements createUndoMove() without copying and swaps the change list on undo.
core/src/main/java/ai/timefold/solver/core/impl/move/EphemeralMoveDirector.java Switches to the new createUndoMove() API.
core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/list/ElementDestinationSelector.java Removes stream usage in iterators and switches to new iterator utilities.
core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/common/iterator/MappingIterator.java Adds a minimal mapping iterator to avoid stream overhead.
core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/common/iterator/ConcatenatingIterator.java Adds a concatenating iterator to avoid stream concatenation overhead.
core/src/main/java/ai/timefold/solver/core/impl/exhaustivesearch/scope/ExhaustiveSearchPhaseScope.java Removes unused depth/expandable tracking and simplifies expandable node addition.
core/src/main/java/ai/timefold/solver/core/impl/exhaustivesearch/node/comparator/ScoreFirstNodeComparator.java Simplifies comparator logic to reduce branching.
core/src/main/java/ai/timefold/solver/core/impl/exhaustivesearch/node/comparator/OriginalOrderNodeComparator.java Simplifies comparator logic to reduce branching.
core/src/main/java/ai/timefold/solver/core/impl/exhaustivesearch/node/comparator/OptimisticBoundFirstNodeComparator.java Simplifies comparator logic to reduce branching.
core/src/main/java/ai/timefold/solver/core/impl/exhaustivesearch/node/comparator/DepthFirstNodeComparator.java Simplifies comparator logic to reduce branching.
core/src/main/java/ai/timefold/solver/core/impl/exhaustivesearch/node/comparator/BreadthFirstNodeComparator.java Simplifies comparator logic to reduce branching.
core/src/main/java/ai/timefold/solver/core/impl/exhaustivesearch/node/ExhaustiveSearchNode.java Removes unused expandable field/accessors.
core/src/main/java/ai/timefold/solver/core/impl/exhaustivesearch/decider/AbstractExhaustiveSearchDecider.java Removes expandable logging and uses getFirst() for layer access.
core/src/main/java/ai/timefold/solver/core/impl/exhaustivesearch/DefaultExhaustiveSearchPhase.java Uses removeLast() to pop the next node more directly.

@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants