Skip to content

Commit

Permalink
Introduce a faster version of the addProperties function (#28969)
Browse files Browse the repository at this point in the history
## Summary

This PR introduces a faster version of the `addProperties` function.
This new function is basically the `diffProperties` with `prevProps` set
to `null`, propagated constants, and all the unreachable code paths
collapsed.

## How did you test this change?

I've tested this change with [the benchmark
app](https://github.com/react-native-community/RNNewArchitectureApp/tree/new-architecture-benchmarks)
and got ~4.4% improvement in the view creation time.

DiffTrain build for commit 73bcdfb.
  • Loading branch information
dmytrorykun committed May 2, 2024
1 parent 10db98e commit 0cb0be9
Show file tree
Hide file tree
Showing 10 changed files with 317 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<4c8919e8adb15c1f31e630f08e73d86f>>
* @generated SignedSource<<af4ef85b8fe75e4033608d078d795833>>
*/

'use strict';
Expand All @@ -25,7 +25,8 @@ var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-e

var enableComponentStackLocations = dynamicFlags.enableComponentStackLocations,
enableRenderableContext = dynamicFlags.enableRenderableContext,
disableDefaultPropsExceptForClasses = dynamicFlags.disableDefaultPropsExceptForClasses; // The rest of the flags are static for better dead code elimination.
disableDefaultPropsExceptForClasses = dynamicFlags.disableDefaultPropsExceptForClasses;
// The rest of the flags are static for better dead code elimination.
var enableDebugTracing = false;
var enableScopeAPI = false;
var enableLegacyHidden = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<659c779c0ac134a5010cd8f6556b1b17>>
* @generated SignedSource<<ce4cd05ddf193df647a49f1ddbcc0aed>>
*/

'use strict';
Expand All @@ -25,7 +25,8 @@ var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-e

var enableComponentStackLocations = dynamicFlags.enableComponentStackLocations,
enableRenderableContext = dynamicFlags.enableRenderableContext,
disableDefaultPropsExceptForClasses = dynamicFlags.disableDefaultPropsExceptForClasses; // The rest of the flags are static for better dead code elimination.
disableDefaultPropsExceptForClasses = dynamicFlags.disableDefaultPropsExceptForClasses;
// The rest of the flags are static for better dead code elimination.
var enableDebugTracing = false;
var enableScopeAPI = false;
var enableLegacyHidden = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<0f88cc3fda756e3467304abd247a3db7>>
* @generated SignedSource<<f47b166be53dccb56c8e3adcf1ba0dfb>>
*/

'use strict';
Expand All @@ -27,7 +27,7 @@ if (
}
var dynamicFlagsUntyped = require('ReactNativeInternalFeatureFlags');

var ReactVersion = '19.0.0-beta-6a68f48e';
var ReactVersion = '19.0.0-beta-45cd200f';

// Re-export dynamic flags from the internal module.
var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-exporting to avoid a dynamic look-up on
Expand All @@ -36,7 +36,8 @@ var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-e
var enableAsyncActions = dynamicFlags.enableAsyncActions,
enableComponentStackLocations = dynamicFlags.enableComponentStackLocations,
enableRenderableContext = dynamicFlags.enableRenderableContext,
disableDefaultPropsExceptForClasses = dynamicFlags.disableDefaultPropsExceptForClasses; // The rest of the flags are static for better dead code elimination.
disableDefaultPropsExceptForClasses = dynamicFlags.disableDefaultPropsExceptForClasses;
// The rest of the flags are static for better dead code elimination.
var enableDebugTracing = false;
var enableScopeAPI = false;
var enableLegacyHidden = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4508873393058e86bed308b56e49ec883ece59d1
73bcdfbae57545aa8f88ecdf67426275610b5573
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<3b1926ec8be22ff21a461aebe15a8dec>>
* @generated SignedSource<<438e1cd98ae204c6c07245d77bdf2eb2>>
*/

'use strict';
Expand Down Expand Up @@ -2003,7 +2003,8 @@ var alwaysThrottleRetries = dynamicFlags.alwaysThrottleRetries,
enableUnifiedSyncLane = dynamicFlags.enableUnifiedSyncLane,
passChildrenWhenCloningPersistedNodes = dynamicFlags.passChildrenWhenCloningPersistedNodes,
useModernStrictMode = dynamicFlags.useModernStrictMode,
disableDefaultPropsExceptForClasses = dynamicFlags.disableDefaultPropsExceptForClasses; // The rest of the flags are static for better dead code elimination.
disableDefaultPropsExceptForClasses = dynamicFlags.disableDefaultPropsExceptForClasses,
enableAddPropertiesFastPath = dynamicFlags.enableAddPropertiesFastPath; // The rest of the flags are static for better dead code elimination.
var enableSchedulingProfiler = true;
var enableProfilerTimer = true;
var enableProfilerCommitHooks = true;
Expand Down Expand Up @@ -2352,14 +2353,70 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) {

return updatePayload;
}

function fastAddProperties(updatePayload, nextProps, validAttributes) {
var attributeConfig;
var nextProp;

for (var propKey in nextProps) {
nextProp = nextProps[propKey];

if (nextProp === undefined) {
continue;
}

attributeConfig = validAttributes[propKey];

if (attributeConfig === undefined) {
continue;
}

if (typeof nextProp === 'function') {
nextProp = true;
}

if (typeof attributeConfig !== 'object') {
if (!updatePayload) {
updatePayload = {};
}

updatePayload[propKey] = nextProp;
continue;
}

if (typeof attributeConfig.process === 'function') {
if (!updatePayload) {
updatePayload = {};
}

updatePayload[propKey] = attributeConfig.process(nextProp);
continue;
}

if (isArray(nextProp)) {
for (var i = 0; i < nextProp.length; i++) {
updatePayload = fastAddProperties(updatePayload, nextProp[i], attributeConfig);
}

continue;
}

updatePayload = fastAddProperties(updatePayload, nextProp, attributeConfig);
}

return updatePayload;
}
/**
* addProperties adds all the valid props to the payload after being processed.
*/


function addProperties(updatePayload, props, validAttributes) {
// TODO: Fast path
return diffProperties(updatePayload, emptyObject$1, props, validAttributes);
if (enableAddPropertiesFastPath) {
return fastAddProperties(updatePayload, props, validAttributes);
} else {
return diffProperties(updatePayload, emptyObject$1, props, validAttributes);
}
}
/**
* clearProperties clears all the previous props by adding a null sentinel
Expand Down Expand Up @@ -26075,7 +26132,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition
return root;
}

var ReactVersion = '19.0.0-beta-197956b7';
var ReactVersion = '19.0.0-beta-8a57d9cf';

/*
* The `'' + value` pattern (used in perf-sensitive code) throws for Symbol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<ad84473bdbce0975ceaaac6469a759ac>>
* @generated SignedSource<<97e06df55397eea2903e5bffade5f61e>>
*/

"use strict";
Expand Down Expand Up @@ -983,6 +983,7 @@ var alwaysThrottleRetries = dynamicFlagsUntyped.alwaysThrottleRetries,
dynamicFlagsUntyped.passChildrenWhenCloningPersistedNodes,
disableDefaultPropsExceptForClasses =
dynamicFlagsUntyped.disableDefaultPropsExceptForClasses,
enableAddPropertiesFastPath = dynamicFlagsUntyped.enableAddPropertiesFastPath,
emptyObject$1 = {},
removedKeys = null,
removedKeyCount = 0,
Expand Down Expand Up @@ -1091,12 +1092,7 @@ function diffNestedProperty(
function addNestedProperty(updatePayload, nextProp, validAttributes) {
if (!nextProp) return updatePayload;
if (!isArrayImpl(nextProp))
return diffProperties(
updatePayload,
emptyObject$1,
nextProp,
validAttributes
);
return addProperties(updatePayload, nextProp, validAttributes);
for (var i = 0; i < nextProp.length; i++)
updatePayload = addNestedProperty(
updatePayload,
Expand Down Expand Up @@ -1206,6 +1202,44 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) {
)))));
return updatePayload;
}
function fastAddProperties(updatePayload, nextProps, validAttributes) {
var propKey;
for (propKey in nextProps) {
var nextProp = nextProps[propKey];
if (void 0 !== nextProp) {
var attributeConfig = validAttributes[propKey];
if (void 0 !== attributeConfig)
if (
("function" === typeof nextProp && (nextProp = !0),
"object" !== typeof attributeConfig)
)
updatePayload || (updatePayload = {}),
(updatePayload[propKey] = nextProp);
else if ("function" === typeof attributeConfig.process)
updatePayload || (updatePayload = {}),
(updatePayload[propKey] = attributeConfig.process(nextProp));
else if (isArrayImpl(nextProp))
for (var i = 0; i < nextProp.length; i++)
updatePayload = fastAddProperties(
updatePayload,
nextProp[i],
attributeConfig
);
else
updatePayload = fastAddProperties(
updatePayload,
nextProp,
attributeConfig
);
}
}
return updatePayload;
}
function addProperties(updatePayload, props, validAttributes) {
return enableAddPropertiesFastPath
? fastAddProperties(updatePayload, props, validAttributes)
: diffProperties(updatePayload, emptyObject$1, props, validAttributes);
}
function batchedUpdatesImpl(fn, bookkeeping) {
return fn(bookkeeping);
}
Expand Down Expand Up @@ -1604,9 +1638,8 @@ var scheduleTimeout = setTimeout,
cancelTimeout = clearTimeout;
function cloneHiddenInstance(instance) {
var node = instance.node;
var JSCompiler_inline_result = diffProperties(
var JSCompiler_inline_result = addProperties(
null,
emptyObject$1,
{ style: { display: "none" } },
instance.canonical.viewConfig.validAttributes
);
Expand Down Expand Up @@ -7351,9 +7384,8 @@ function completeWork(current, workInProgress, renderLanes) {
current = nextReactTag;
nextReactTag += 2;
renderLanes = getViewConfigForType(renderLanes);
newChildSet = diffProperties(
newChildSet = addProperties(
null,
emptyObject$1,
newProps,
renderLanes.validAttributes
);
Expand Down Expand Up @@ -10613,7 +10645,7 @@ var roots = new Map(),
devToolsConfig$jscomp$inline_1118 = {
findFiberByHostInstance: getInstanceFromNode,
bundleType: 0,
version: "19.0.0-beta-9a489885",
version: "19.0.0-beta-5fd3967c",
rendererPackageName: "react-native-renderer",
rendererConfig: {
getInspectorDataForInstance: getInspectorDataForInstance,
Expand Down Expand Up @@ -10656,7 +10688,7 @@ var internals$jscomp$inline_1385 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-beta-9a489885"
reconcilerVersion: "19.0.0-beta-5fd3967c"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1386 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
Loading

0 comments on commit 0cb0be9

Please sign in to comment.