From 894ee722787b18cf2fdfc657781c917c737d37d8 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Sun, 3 Nov 2019 14:52:18 -0800 Subject: [PATCH] Collapse Delete-Create mounting instructions Summary: This diff implements an optimization / fix in the mounting layer of Fabric Android to ignore the "deletion" and "creation" of views for the same tag in the same commit. This operation is adding ~100 ns for every commit (I measured this using a release APK running in a real device). I created a QE to enable / disable this optimization and to measure the performance impact of this change in production Changelog: Implement optimization in mounting layer of Fabric Reviewed By: JoshuaGross Differential Revision: D18279240 fbshipit-source-id: d6fdeb2a9676bcfaf47886893eed5024bf86204b --- .../java/com/facebook/react/fabric/jni/BUCK | 1 + .../com/facebook/react/fabric/jni/Binding.cpp | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/BUCK b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/BUCK index 75b75835b3b..a804631c65a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/BUCK @@ -26,6 +26,7 @@ rn_xplat_cxx_library( soname = "libfabricjni.$(ext)", visibility = ["PUBLIC"], deps = [ + react_native_xplat_target("better:better"), react_native_xplat_target("config:config"), react_native_xplat_target("fabric/uimanager:uimanager"), react_native_xplat_target("fabric/components/scrollview:scrollview"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp index ef67cc68163..e47befe09cc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp @@ -11,6 +11,7 @@ #include "ReactNativeConfigHolder.h" #include "StateWrapperImpl.h" +#import #include #include #include @@ -572,6 +573,21 @@ void Binding::schedulerDidFinishTransaction( auto surfaceId = mountingTransaction->getSurfaceId(); auto &mutations = mountingTransaction->getMutations(); + facebook::better::set createAndDeleteTagsToProcess; + if (collapseDeleteCreateMountingInstructions_) { + for (const auto &mutation : mutations) { + if (mutation.type == ShadowViewMutation::Delete) { + createAndDeleteTagsToProcess.insert(mutation.oldChildShadowView.tag); + } else if (mutation.type == ShadowViewMutation::Create) { + int tag = mutation.oldChildShadowView.tag; + if (createAndDeleteTagsToProcess.find(tag) != createAndDeleteTagsToProcess.end()) { + createAndDeleteTagsToProcess.erase(tag); + } else { + createAndDeleteTagsToProcess.insert(tag); + } + } + } + } int64_t commitNumber = telemetry.getCommitNumber(); std::vector> queue; @@ -591,6 +607,14 @@ void Binding::schedulerDidFinishTransaction( for (const auto &mutation : mutations) { auto oldChildShadowView = mutation.oldChildShadowView; auto newChildShadowView = mutation.newChildShadowView; + auto mutationType = mutation.type; + + if (collapseDeleteCreateMountingInstructions_ && + (mutationType == ShadowViewMutation::Create || mutationType == ShadowViewMutation::Delete) && + createAndDeleteTagsToProcess.size() > 0 && + createAndDeleteTagsToProcess.find(mutation.newChildShadowView.tag) == createAndDeleteTagsToProcess.end()) { + continue; + } bool isVirtual = newChildShadowView.layoutMetrics == EmptyLayoutMetrics && oldChildShadowView.layoutMetrics == EmptyLayoutMetrics;