Index: core/optaplanner-core-impl/src/main/java/org/optaplanner/core/impl/heuristic/selector/move/generic/list/SubListChangeMove.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/core/optaplanner-core-impl/src/main/java/org/optaplanner/core/impl/heuristic/selector/move/generic/list/SubListChangeMove.java b/core/optaplanner-core-impl/src/main/java/org/optaplanner/core/impl/heuristic/selector/move/generic/list/SubListChangeMove.java
--- a/core/optaplanner-core-impl/src/main/java/org/optaplanner/core/impl/heuristic/selector/move/generic/list/SubListChangeMove.java	(revision 2e145dcde89b51b5c0d973b7e63685edc972c39e)
+++ b/core/optaplanner-core-impl/src/main/java/org/optaplanner/core/impl/heuristic/selector/move/generic/list/SubListChangeMove.java	(date 1669724599815)
@@ -2,11 +2,8 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Objects;
-import java.util.Set;
 
 import org.optaplanner.core.api.domain.solution.PlanningSolution;
 import org.optaplanner.core.api.score.director.ScoreDirector;
@@ -96,18 +93,14 @@
 
         List<Object> sourceList = variableDescriptor.getListVariable(sourceEntity);
         List<Object> subList = sourceList.subList(sourceIndex, sourceIndex + length);
-        List<Object> subListCopy = new ArrayList<>(subList);
-        if (reversing) {
-            Collections.reverse(subListCopy);
-        }
-        planningValues = subListCopy;
+        planningValues = copyList(subList, reversing);
 
         if (sourceEntity == destinationEntity) {
             int fromIndex = Math.min(sourceIndex, destinationIndex);
             int toIndex = Math.max(sourceIndex, destinationIndex) + length;
             innerScoreDirector.beforeListVariableChanged(variableDescriptor, sourceEntity, fromIndex, toIndex);
             subList.clear();
-            variableDescriptor.getListVariable(destinationEntity).addAll(destinationIndex, subListCopy);
+            variableDescriptor.getListVariable(destinationEntity).addAll(destinationIndex, planningValues);
             innerScoreDirector.afterListVariableChanged(variableDescriptor, sourceEntity, fromIndex, toIndex);
         } else {
             innerScoreDirector.beforeListVariableChanged(variableDescriptor,
@@ -117,12 +110,23 @@
                     sourceEntity, sourceIndex, sourceIndex);
             innerScoreDirector.beforeListVariableChanged(variableDescriptor,
                     destinationEntity, destinationIndex, destinationIndex);
-            variableDescriptor.getListVariable(destinationEntity).addAll(destinationIndex, subListCopy);
+            variableDescriptor.getListVariable(destinationEntity).addAll(destinationIndex, planningValues);
             innerScoreDirector.afterListVariableChanged(variableDescriptor,
                     destinationEntity, destinationIndex, destinationIndex + length);
         }
     }
 
+    static List<Object> copyList(List<Object> originalList, boolean reverse) {
+        int lastIndex = originalList.size() - 1;
+        List<Object> result = new ArrayList<>(originalList.size());
+        // Reverse = fill the list in reverse order (iterate backwards).
+        // This is more efficient than filling the list in original order and then reversing it.
+        for (int i = (reverse ? lastIndex : 0); (reverse ? i >= 0 : i <= lastIndex); i += (reverse ? -1 : 1)) {
+            result.add(originalList.get(i));
+        }
+        return result;
+    }
+
     @Override
     public SubListChangeMove<Solution_> rebase(ScoreDirector<Solution_> destinationScoreDirector) {
         return new SubListChangeMove<>(
@@ -143,11 +147,11 @@
 
     @Override
     public Collection<Object> getPlanningEntities() {
-        // Use LinkedHashSet for predictable iteration order.
-        Set<Object> entities = new LinkedHashSet<>(2);
-        entities.add(sourceEntity);
-        entities.add(destinationEntity);
-        return entities;
+        if (sourceEntity == destinationEntity) {
+            return List.of(sourceEntity);
+        } else {
+            return List.of(sourceEntity, destinationEntity);
+        }
     }
 
     @Override
Index: core/optaplanner-core-impl/src/main/java/org/optaplanner/core/impl/heuristic/selector/move/generic/list/SubListSwapMove.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/core/optaplanner-core-impl/src/main/java/org/optaplanner/core/impl/heuristic/selector/move/generic/list/SubListSwapMove.java b/core/optaplanner-core-impl/src/main/java/org/optaplanner/core/impl/heuristic/selector/move/generic/list/SubListSwapMove.java
--- a/core/optaplanner-core-impl/src/main/java/org/optaplanner/core/impl/heuristic/selector/move/generic/list/SubListSwapMove.java	(revision 2e145dcde89b51b5c0d973b7e63685edc972c39e)
+++ b/core/optaplanner-core-impl/src/main/java/org/optaplanner/core/impl/heuristic/selector/move/generic/list/SubListSwapMove.java	(date 1669724410513)
@@ -1,8 +1,6 @@
 package org.optaplanner.core.impl.heuristic.selector.move.generic.list;
 
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Objects;
@@ -106,15 +104,9 @@
         List<Object> rightList = variableDescriptor.getListVariable(rightEntity);
         List<Object> leftSubListView = subList(leftSubList);
         List<Object> rightSubListView = subList(rightSubList);
-        List<Object> leftSubListCopy = new ArrayList<>(leftSubListView);
-        List<Object> rightSubListCopy = new ArrayList<>(rightSubListView);
-        if (reversing) {
-            Collections.reverse(leftSubListCopy);
-            Collections.reverse(rightSubListCopy);
-        }
 
-        leftPlanningValues = leftSubListCopy;
-        rightPlanningValues = rightSubListCopy;
+        leftPlanningValues = SubListChangeMove.copyList(leftSubListView, reversing);
+        rightPlanningValues = SubListChangeMove.copyList(rightSubListView, reversing);
 
         if (leftEntity == rightEntity) {
             int fromIndex = Math.min(leftFromIndex, rightFromIndex);
@@ -125,8 +117,8 @@
             innerScoreDirector.beforeListVariableChanged(variableDescriptor, leftEntity, fromIndex, toIndex);
             rightSubListView.clear();
             subList(leftSubList).clear();
-            leftList.addAll(leftFromIndex, rightSubListCopy);
-            rightList.addAll(leftSubListDestinationIndex, leftSubListCopy);
+            leftList.addAll(leftFromIndex, rightPlanningValues);
+            rightList.addAll(leftSubListDestinationIndex, leftPlanningValues);
             innerScoreDirector.afterListVariableChanged(variableDescriptor, leftEntity, fromIndex, toIndex);
         } else {
             innerScoreDirector.beforeListVariableChanged(variableDescriptor,
@@ -135,8 +127,8 @@
                     rightEntity, rightFromIndex, rightFromIndex + rightSubListLength);
             rightSubListView.clear();
             leftSubListView.clear();
-            leftList.addAll(leftFromIndex, rightSubListCopy);
-            rightList.addAll(rightFromIndex, leftSubListCopy);
+            leftList.addAll(leftFromIndex, rightPlanningValues);
+            rightList.addAll(rightFromIndex, leftPlanningValues);
             innerScoreDirector.afterListVariableChanged(variableDescriptor,
                     leftEntity, leftFromIndex, leftFromIndex + rightSubListLength);
             innerScoreDirector.afterListVariableChanged(variableDescriptor,
