Skip to content

Commit 92d3fdb

Browse files
authored
perf: avoid calling Object.hashCode() (#2382)
1 parent 83ae0ee commit 92d3fdb

2 files changed

Lines changed: 7 additions & 27 deletions

File tree

core/src/main/java/ai/timefold/solver/core/impl/domain/variable/declarative/AbstractVariableReferenceGraph.java

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ public abstract sealed class AbstractVariableReferenceGraph<Solution_, ChangeTra
4343
nodeList = List.copyOf(outerGraph.nodeList);
4444
var instanceCount = nodeList.size();
4545
// Often the maps are a singleton; we improve performance by actually making it so.
46-
variableReferenceToContainingNodeMap = mapOfMapsDeepCopyOf(outerGraph.variableReferenceToContainingNodeMap);
47-
variableReferenceToBeforeProcessor = mapOfListsDeepCopyOf(outerGraph.variableReferenceToBeforeProcessor);
48-
variableReferenceToAfterProcessor = mapOfListsDeepCopyOf(outerGraph.variableReferenceToAfterProcessor);
46+
variableReferenceToContainingNodeMap = Map.copyOf(outerGraph.variableReferenceToContainingNodeMap);
47+
variableReferenceToBeforeProcessor = Map.copyOf(outerGraph.variableReferenceToBeforeProcessor);
48+
variableReferenceToAfterProcessor = Map.copyOf(outerGraph.variableReferenceToAfterProcessor);
4949
edgeCount = new DynamicLinearProbeNonNegativeIntCounter[instanceCount];
50-
for (int i = 0; i < instanceCount; i++) {
50+
for (var i = 0; i < instanceCount; i++) {
5151
edgeCount[i] = new DynamicLinearProbeNonNegativeIntCounter();
5252
}
5353
graph = graphCreator.apply(instanceCount);
@@ -171,7 +171,7 @@ private void processEntity(List<BiConsumer<AbstractVariableReferenceGraph<Soluti
171171
var processorCount = processorList.size();
172172
// Avoid creation of iterators on the hot path.
173173
// The short-lived instances were observed to cause considerable GC pressure.
174-
for (int i = 0; i < processorCount; i++) {
174+
for (var i = 0; i < processorCount; i++) {
175175
processorList.get(i).accept(this, entity);
176176
}
177177
}
@@ -207,22 +207,4 @@ public String toString() {
207207

208208
}
209209

210-
@SuppressWarnings("unchecked")
211-
static <K1, K2, V> Map<K1, Map<K2, V>> mapOfMapsDeepCopyOf(Map<K1, Map<K2, V>> map) {
212-
var entryArray = map.entrySet()
213-
.stream()
214-
.map(e -> Map.entry(e.getKey(), Map.copyOf(e.getValue())))
215-
.toArray(Map.Entry[]::new);
216-
return Map.ofEntries(entryArray);
217-
}
218-
219-
@SuppressWarnings("unchecked")
220-
static <K1, V> Map<K1, List<V>> mapOfListsDeepCopyOf(Map<K1, List<V>> map) {
221-
var entryArray = map.entrySet()
222-
.stream()
223-
.map(e -> Map.entry(e.getKey(), List.copyOf(e.getValue())))
224-
.toArray(Map.Entry[]::new);
225-
return Map.ofEntries(entryArray);
226-
}
227-
228210
}

core/src/main/java/ai/timefold/solver/core/impl/domain/variable/declarative/DefaultVariableReferenceGraph.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,18 @@ public DefaultVariableReferenceGraph(VariableReferenceGraphBuilder<Solution_> ou
2323
entityToVariableReferenceMap.computeIfAbsent(entity, ignored -> new ArrayList<>())
2424
.add(instance);
2525
} else {
26-
for (var groupEntity : instance.variableReferences().get(0).groupEntities()) {
26+
for (var groupEntity : instance.variableReferences().getFirst().groupEntities()) {
2727
entityToVariableReferenceMap.computeIfAbsent(groupEntity, ignored -> new ArrayList<>())
2828
.add(instance);
2929
}
3030
}
3131
}
32-
// Immutable optimized version of the map, now that it won't be updated anymore.
33-
var immutableEntityToVariableReferenceMap = mapOfListsDeepCopyOf(entityToVariableReferenceMap);
3432
// This mutable structure is created once, and reused from there on.
3533
// Otherwise its internal collections were observed being re-created so often
3634
// that the allocation of arrays would become a major bottleneck.
3735
affectedEntitiesUpdater =
3836
new AffectedEntitiesUpdater<>(graph, nodeList, nodeTopologicalOrders,
39-
immutableEntityToVariableReferenceMap::get,
37+
entityToVariableReferenceMap::get,
4038
outerGraph.entityToEntityId.size(), outerGraph.changedVariableNotifier);
4139
}
4240

0 commit comments

Comments
 (0)