Files
react-native/ReactCommon/fabric/mounting/Differentiator.h
T
Joshua Gross 50a34bcd7f 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
2020-03-27 19:07:53 -07:00

37 lines
998 B
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <react/core/ShadowNode.h>
#include <react/mounting/ShadowViewMutation.h>
namespace facebook {
namespace react {
enum class DifferentiatorMode { Classic, OptimizedMoves };
/*
* Calculates a list of view mutations which describes how the old
* `ShadowTree` can be transformed to the new one.
* The list of mutations might be and might not be optimal.
*/
ShadowViewMutationList calculateShadowViewMutations(
DifferentiatorMode differentiatorMode,
ShadowNode const &oldRootShadowNode,
ShadowNode const &newRootShadowNode);
/*
* Generates a list of `ShadowViewNodePair`s that represents a layer of a
* flattened view hierarchy.
*/
ShadowViewNodePair::List sliceChildShadowNodeViewPairs(
ShadowNode const &shadowNode);
} // namespace react
} // namespace facebook