diff --git a/flow-typed/npm/tinybench_v4.1.x.js b/flow-typed/npm/tinybench_v4.1.x.js index a40214d96733..56412034a9d6 100644 --- a/flow-typed/npm/tinybench_v4.1.x.js +++ b/flow-typed/npm/tinybench_v4.1.x.js @@ -91,10 +91,15 @@ declare module 'tinybench' { beforeEach?: (this: Task) => void | Promise, }; - export interface FnReturnedObject { - overriddenDuration?: number; - } + // This is defined as an interface in tinybench but we define it as an object + // to catch problems like `overriddenDuration` being misspelled. + export type FnReturnedObject = { + overriddenDuration?: number, + }; + // This type is defined as returning `unknown` instead of `void` in tinybench, + // but we type it this way to avoid mistakes (we can make breaking changes + // in our definition that they can't). export type Fn = () => | Promise | void diff --git a/private/react-native-fantom/src/Benchmark.js b/private/react-native-fantom/src/Benchmark.js index f5a78dca345c..2871312ef1aa 100644 --- a/private/react-native-fantom/src/Benchmark.js +++ b/private/react-native-fantom/src/Benchmark.js @@ -15,11 +15,13 @@ import NativeCPUTime from 'react-native/src/private/testing/fantom/specs/NativeC import { Bench, type BenchOptions, - type Fn, type FnOptions, + type FnReturnedObject, type TaskResult, } from 'tinybench'; +type SyncFn = () => FnReturnedObject | void; + export type SuiteOptions = $ReadOnly<{ minIterations?: number, minDuration?: number, @@ -66,20 +68,20 @@ interface ParameterizedTestFunction { ( testArgs: $ReadOnlyArray, name: TestWithArgName, - fn: (testArg: TestArgType) => ReturnType, + fn: (testArg: TestArgType) => ReturnType, options?: TestWithArgOptions, ): SuiteAPI; only: ( testArgs: $ReadOnlyArray, name: TestWithArgName, - fn: (testArg: TestArgType) => ReturnType, + fn: (testArg: TestArgType) => ReturnType, options?: TestWithArgOptions, ) => SuiteAPI; } interface TestFunction { - (name: string, fn: Fn, options?: FnOptions): SuiteAPI; - only: (name: string, fn: Fn, options?: FnOptions) => SuiteAPI; + (name: string, fn: SyncFn, options?: FnOptions): SuiteAPI; + only: (name: string, fn: SyncFn, options?: FnOptions) => SuiteAPI; // `each` allows to run the same test multiple times with different arguments, provided as an array of values: each: ParameterizedTestFunction; } @@ -91,7 +93,7 @@ interface SuiteAPI { interface TestTask { name: string; - fn: Fn; + fn: SyncFn; options: InternalTestOptions | void; } @@ -174,10 +176,16 @@ export function suite( bench.add(task.name, task.fn, options); } + if (!isTestOnly) { + console.log(`Running benchmark: ${suiteName}. Please wait.`); + } + + const runStartTime = performance.now(); + bench.runSync(); if (!isTestOnly) { - printBenchmarkResults(bench); + printBenchmarkResults(bench, runStartTime); } for (const verify of verifyFns) { @@ -202,12 +210,12 @@ export function suite( reportBenchmarkResult(createBenchmarkResultsObject(bench, tasks)); }); - const test = (name: string, fn: Fn, options?: FnOptions): SuiteAPI => { + const test = (name: string, fn: SyncFn, options?: FnOptions): SuiteAPI => { tasks.push({name, fn, options}); return suiteAPI; }; - test.only = (name: string, fn: Fn, options?: FnOptions): SuiteAPI => { + test.only = (name: string, fn: SyncFn, options?: FnOptions): SuiteAPI => { tasks.push({name, fn, options: {...options, only: true}}); return suiteAPI; }; @@ -215,7 +223,7 @@ export function suite( const testWithArg = ( testArg: TestArgType, name: TestWithArgName, - fn: (testArg: TestArgType) => ReturnType, + fn: (testArg: TestArgType) => ReturnType, options?: TestWithArgOptions, only?: boolean = false, ): TestTask => { @@ -233,7 +241,7 @@ export function suite( const testEach: ParameterizedTestFunction = ( testArgs: $ReadOnlyArray, name: TestWithArgName, - fn: (testArg: TestArgType) => ReturnType, + fn: (testArg: TestArgType) => ReturnType, options?: TestWithArgOptions, ): SuiteAPI => { for (const testArg of testArgs) { @@ -262,16 +270,24 @@ export function suite( return suiteAPI; } -function printBenchmarkResults(bench: Bench) { +function printBenchmarkResults(bench: Bench, runStartTime: number) { const {fantomConfigSummary} = getConstants(); const benchmarkName = (bench.name ?? 'Benchmark') + (fantomConfigSummary ? ` (${fantomConfigSummary})` : ''); + const runDuration = performance.now() - runStartTime; + const durationStr = + runDuration < 1000 + ? `${runDuration.toFixed(0)}ms` + : `${(runDuration / 1000).toFixed(0)}s`; + console.log(''); console.log(`### ${benchmarkName} ###`); console.table(nullthrows(bench.table())); console.log(''); + console.log(`Total benchmark duration: ${durationStr}`); + console.log(''); } function createBenchmarkResultsObject(