Skip to content

perf: avoid calling Object.hashCode()#2382

Merged
triceo merged 1 commit into
TimefoldAI:mainfrom
triceo:monomorphic
Jun 19, 2026
Merged

perf: avoid calling Object.hashCode()#2382
triceo merged 1 commit into
TimefoldAI:mainfrom
triceo:monomorphic

Conversation

@triceo

@triceo triceo commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

Replacing IdentityHashMap with a Map.of(...) when the keys in that map are of several different classes (such as multiple entity classes) will result in System.identityHashCode(...) being replaced by Object.hashCode() - a megamorphic call that the JVM can't optimize.

Copilot AI review requested due to automatic review settings June 17, 2026 13:19
@triceo triceo self-assigned this Jun 17, 2026
@triceo triceo added this to the v2.3.0 milestone Jun 17, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 aims to prevent performance regressions caused by converting identity-based maps to Map.of(...)/Map.ofEntries(...), which can trigger megamorphic Object.hashCode() calls when keys are heterogeneous (e.g., multiple entity classes).

Changes:

  • Replace deep-copy helpers that used Map.ofEntries(...) with Map.copyOf(...) to avoid building immutable maps that depend on Object.hashCode().
  • Preserve IdentityHashMap usage for hot-path entity lookups by avoiding conversions that lose identity semantics.
  • Minor loop micro-optimizations (int ivar i) in a couple of hot-path loops.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
core/src/main/java/ai/timefold/solver/core/impl/domain/variable/declarative/DefaultVariableReferenceGraph.java Changes map finalization strategy for entity→nodes lookup used to initialize the updater.
core/src/main/java/ai/timefold/solver/core/impl/domain/variable/declarative/AbstractVariableReferenceGraph.java Replaces Map.ofEntries(...) deep-copy helpers with Map.copyOf(...) to avoid Object.hashCode() megamorphism and removes helper methods accordingly.

Replacing IdentityHashMap with a Map.of(...) when the keys in that map are of several different classes (such as multiple entity classes) will result in System.identityHashCode(...) being replaced by Object.hashCode() - a megamorphic call that the JVM can't optimize.
Copilot AI review requested due to automatic review settings June 17, 2026 14:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

@sonarqubecloud

Copy link
Copy Markdown

@triceo triceo merged commit 92d3fdb into TimefoldAI:main Jun 19, 2026
19 checks passed
@triceo triceo deleted the monomorphic branch June 19, 2026 10:41
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.

3 participants