From cb308bdc5e66f7587a1e834cfd8f334fa97642a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Mon, 6 Jan 2025 07:10:28 -0800 Subject: [PATCH] Add benchmark for host component class variants (#48450) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/48450 Changelog: [internal] This implements a basic benchmark to compare `ReactFabricHostComponent` and `ReactNativeElement` (legacy and DOM implementations for native component instances). Reviewed By: rshest Differential Revision: D66698546 fbshipit-source-id: dd4bde833e5c9eb32c79a52d06f3c360fb012e23 --- ...actFabricPublicInstance-benchmark-itest.js | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 packages/react-native/Libraries/ReactNative/ReactFabricPublicInstance/__tests__/ReactFabricPublicInstance-benchmark-itest.js diff --git a/packages/react-native/Libraries/ReactNative/ReactFabricPublicInstance/__tests__/ReactFabricPublicInstance-benchmark-itest.js b/packages/react-native/Libraries/ReactNative/ReactFabricPublicInstance/__tests__/ReactFabricPublicInstance-benchmark-itest.js new file mode 100644 index 00000000000..aa3c9e981a6 --- /dev/null +++ b/packages/react-native/Libraries/ReactNative/ReactFabricPublicInstance/__tests__/ReactFabricPublicInstance-benchmark-itest.js @@ -0,0 +1,61 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + * @oncall react_native + */ + +import '../../../Core/InitializeCore.js'; +import type { + InternalInstanceHandle, + ViewConfig, +} from '../../../Renderer/shims/ReactNativeTypes'; + +import ReactNativeElement from '../../../../src/private/webapis/dom/nodes/ReactNativeElement'; +import ReactFabricHostComponent from '../../../ReactNative/ReactFabricPublicInstance/ReactFabricHostComponent'; +import {benchmark} from '@react-native/fantom'; +import nullthrows from 'nullthrows'; + +// Create fake parameters for the class. +const tag = 11; +const viewConfig: ViewConfig = { + uiViewClassName: 'test', + validAttributes: { + style: {}, + }, +}; +// $FlowExpectedError[incompatible-type] +const internalInstanceHandle: InternalInstanceHandle = {}; + +benchmark + .suite('ReactNativeElement vs. ReactFabricHostComponent') + .add('ReactNativeElement', () => { + // eslint-disable-next-line no-new + new ReactNativeElement(tag, viewConfig, internalInstanceHandle); + }) + .add('ReactFabricHostComponent', () => { + // eslint-disable-next-line no-new + new ReactFabricHostComponent(tag, viewConfig, internalInstanceHandle); + }) + .verify(([modernImplResults, legacyImplResults]) => { + const minMedian = Math.min( + nullthrows(modernImplResults.latency.p50), + nullthrows(legacyImplResults.latency.p50), + ); + const maxMedian = Math.max( + nullthrows(modernImplResults.latency.p50), + nullthrows(legacyImplResults.latency.p50), + ); + + const medianDifferencePercent = ((maxMedian - minMedian) / minMedian) * 100; + console.log( + `Difference in p50 values between ReactFabricHostComponent and ReactNativeElement is ${medianDifferencePercent.toFixed(2)}%`, + ); + + // No implementation should be more than 25% slower than the other. + expect(medianDifferencePercent).toBeLessThan(25); + });