mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Optimize diff algorithm to produce fewer remove+insert ("move") paired instructions
Summary: An evolution of D20633188 but more performant. There are three optimized paths before the slow path. The first optimized path tries to pair identical nodes from old/new tree, and generate Update mutations, until we hit nodes that are different (indicating either a remove or an insert). This already existed. The next two optimizations, introduced by Tim in his JS pseudocode, were inspired by ReactJS's diffing algorithm. They work in cases where the rest of the nodes are (1) all removals/deletes or (2) all creates+inserts. Finally, if those final two optimized paths can't run, it's because there is a mix of delete+remove, create+insert, and "move" operations, mixed at the beginning, middle, and/or end of the list. This has slightly better average/best-case complexity as the previous implementation. In particularly pathological cases where all nodes are arbitrarily reordered, or reversed, for instance (ABCDE->EDCBA) the algorithm has the same complexity as the previous algorithm (quadratic). For now iOS is pinned to the older differ Changelog: [Internal] Experiment to optimize diffing algorithm in Fabric Reviewed By: shergin Differential Revision: D20684094 fbshipit-source-id: d29fba95a0328156c023e1c87804f23770ee1d91
This commit is contained in:
committed by
Facebook GitHub Bot
parent
24b79c1182
commit
50a34bcd7f
@@ -261,6 +261,9 @@ void Binding::installFabricUIManager(
|
||||
disablePreallocateViews_ = reactNativeConfig_->getBool(
|
||||
"react_fabric:disabled_view_preallocation_android");
|
||||
|
||||
enableOptimizedMovesDiffer_ = reactNativeConfig_->getBool(
|
||||
"react_fabric:enabled_optimized_moves_differ_android");
|
||||
|
||||
auto toolbox = SchedulerToolbox{};
|
||||
toolbox.contextContainer = contextContainer;
|
||||
toolbox.componentRegistryFactory = componentsRegistry->buildRegistryFunction;
|
||||
@@ -570,7 +573,9 @@ void Binding::schedulerDidFinishTransaction(
|
||||
return;
|
||||
}
|
||||
|
||||
auto mountingTransaction = mountingCoordinator->pullTransaction();
|
||||
auto mountingTransaction = mountingCoordinator->pullTransaction(
|
||||
enableOptimizedMovesDiffer_ ? DifferentiatorMode::OptimizedMoves
|
||||
: DifferentiatorMode::Classic);
|
||||
|
||||
if (!mountingTransaction.has_value()) {
|
||||
return;
|
||||
|
||||
@@ -108,6 +108,7 @@ class Binding : public jni::HybridClass<Binding>, public SchedulerDelegate {
|
||||
bool collapseDeleteCreateMountingInstructions_{false};
|
||||
bool disablePreallocateViews_{false};
|
||||
bool disableVirtualNodePreallocation_{false};
|
||||
bool enableOptimizedMovesDiffer_{false};
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
||||
Reference in New Issue
Block a user