Skip to content

Commit 97617cc

Browse files
author
fbchen
committed
optimize constraint calculation performance
1 parent 7d1bc51 commit 97617cc

File tree

1 file changed

+44
-10
lines changed

1 file changed

+44
-10
lines changed

lib/src/constraint_layout.dart

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2520,6 +2520,18 @@ class _ConstraintRenderBox extends RenderBox
25202520
_needsReorderEventOrder = true;
25212521
}
25222522

2523+
static void insertionSort<E>(List<E> a, int Function(E a, E b) compare) {
2524+
for (int i = 1, lastIndex = a.length - 1; i <= lastIndex; i++) {
2525+
var el = a[i];
2526+
int j = i;
2527+
while ((j > 0) && (compare(a[j - 1], el) > 0)) {
2528+
a[j] = a[j - 1];
2529+
j--;
2530+
}
2531+
a[j] = el;
2532+
}
2533+
}
2534+
25232535
@override
25242536
void performLayout() {
25252537
Stopwatch? stopwatch;
@@ -2601,27 +2613,49 @@ class _ConstraintRenderBox extends RenderBox
26012613
return true;
26022614
}());
26032615

2604-
/// Sort by the depth of constraint from shallow to deep, the lowest depth is 0, representing parent
2605-
_layoutOrderList = nodesMap.values.toList();
2606-
if (!selfSizeConfirmed) {
2607-
_layoutOrderList.add(parentNode!);
2616+
if (childCount > 20) {
2617+
// Count sort by child depth, the complexity is O(n)
2618+
List<List<_ConstrainedNode>> bucket =
2619+
List.generate(childCount * 2 + 1, (_) => []);
2620+
for (final element in nodesMap.values) {
2621+
bucket[element.getDepth(
2622+
selfSizeConfirmed, resolvedWidth, resolvedHeight)]
2623+
.add(element);
2624+
}
2625+
if (!selfSizeConfirmed) {
2626+
bucket[childCount + 1].add(parentNode!);
2627+
}
2628+
_layoutOrderList = [];
2629+
for (final element in bucket) {
2630+
if (element.isNotEmpty) {
2631+
_layoutOrderList.addAll(element);
2632+
}
2633+
}
2634+
} else {
2635+
_layoutOrderList = nodesMap.values.toList();
2636+
if (!selfSizeConfirmed) {
2637+
_layoutOrderList.add(parentNode!);
2638+
}
2639+
insertionSort<_ConstrainedNode>(_layoutOrderList, (left, right) {
2640+
return left.getDepth(
2641+
selfSizeConfirmed, resolvedWidth, resolvedHeight) -
2642+
right.getDepth(selfSizeConfirmed, resolvedWidth, resolvedHeight);
2643+
});
26082644
}
2609-
_layoutOrderList.sort((left, right) {
2610-
return left.getDepth(selfSizeConfirmed, resolvedWidth, resolvedHeight) -
2611-
right.getDepth(selfSizeConfirmed, resolvedWidth, resolvedHeight);
2612-
});
26132645

2646+
// Most of the time, it is basically ordered, and the complexity is O(n)
26142647
_paintingOrderList = nodesMap.values.toList();
2615-
_paintingOrderList.sort((left, right) {
2648+
insertionSort<_ConstrainedNode>(_paintingOrderList, (left, right) {
26162649
int result = left.zIndex - right.zIndex;
26172650
if (result == 0) {
26182651
result = left.index - right.index;
26192652
}
26202653
return result;
26212654
});
26222655

2656+
// Most of the time, it is basically ordered, and the complexity is O(n)
26232657
_eventOrderList = nodesMap.values.toList();
2624-
_eventOrderList.sort((left, right) {
2658+
insertionSort<_ConstrainedNode>(_eventOrderList, (left, right) {
26252659
int result = left.eIndex - right.eIndex;
26262660
if (result == 0) {
26272661
result = left.index - right.index;

0 commit comments

Comments
 (0)