Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: quick 3 run scheme #427

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions packages/reassure-measure/src/__tests__/measure-function.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,15 @@ test('measureFunctionInternal applies dropsWorst option', () => {
expect(results.meanCount).toBe(1);
expect(results.stdevCount).toBe(0);
});

test('measureFunctionInternal supports "runs: quick-3" option', () => {
const fn = jest.fn(() => fib(5));
const results = measureFunctionInternal(fn, { runs: 'quick-3', warmupRuns: 1 });

expect(fn).toHaveBeenCalledTimes(4);
expect(results.runs).toBe(6);
expect(results.durations).toHaveLength(6);
expect(results.counts).toHaveLength(6);
expect(results.meanCount).toBe(1);
expect(results.stdevCount).toBe(0);
});
25 changes: 22 additions & 3 deletions packages/reassure-measure/src/__tests__/measure-helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ test('processRunResults calculates correct means and stdevs', () => {
{ duration: 14, count: 2 },
];

expect(processRunResults(input, 0)).toEqual({
expect(processRunResults(input, 3, 0)).toEqual({
runs: 3,
meanDuration: 12,
stdevDuration: 2,
Expand All @@ -20,13 +20,13 @@ test('processRunResults calculates correct means and stdevs', () => {

test('processRunResults applies warmupRuns option', () => {
const input = [
{ duration: 23, count: 1 },
{ duration: 23, count: 1 }, // warmup run
{ duration: 20, count: 5 },
{ duration: 24, count: 5 },
{ duration: 22, count: 5 },
];

expect(processRunResults(input, 1)).toEqual({
expect(processRunResults(input, 4, 1)).toEqual({
runs: 3,
meanDuration: 22,
stdevDuration: 2,
Expand All @@ -36,3 +36,22 @@ test('processRunResults applies warmupRuns option', () => {
counts: [5, 5, 5],
});
});

test('processRunResults supports "runs: quick-3" option', () => {
const input = [
{ duration: 100, count: 1 }, // warmup run
{ duration: 1, count: 5 },
{ duration: 6, count: 5 },
{ duration: 29, count: 5 },
];

expect(processRunResults(input, 'quick-3', 1)).toEqual({
runs: 6,
meanDuration: 9,
stdevDuration: 10,
durations: [29, 6, 6, 6, 6, 1],
meanCount: 5,
stdevCount: 0,
counts: [5, 5, 5, 5, 5, 5],
});
});
24 changes: 24 additions & 0 deletions packages/reassure-measure/src/__tests__/measure-render.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,27 @@ test('buildUiToRender does not wrap when no wrapper is passed', () => {
</UNDEFINED>
`);
});

test('measureRender applies dropsWorst option', async () => {
const scenario = jest.fn(() => Promise.resolve(null));
const results = await measureRender(<View />, { runs: 10, warmupRuns: 1, scenario });

expect(scenario).toHaveBeenCalledTimes(11);
expect(results.runs).toBe(10);
expect(results.durations).toHaveLength(10);
expect(results.counts).toHaveLength(10);
expect(results.meanCount).toBe(1);
expect(results.stdevCount).toBe(0);
});

test('measureRender supports "runs: quick-3" option', async () => {
const scenario = jest.fn(() => Promise.resolve(null));
const results = await measureRender(<View />, { runs: 'quick-3', warmupRuns: 1, scenario });

expect(scenario).toHaveBeenCalledTimes(4);
expect(results.runs).toBe(6);
expect(results.durations).toHaveLength(6);
expect(results.counts).toHaveLength(6);
expect(results.meanCount).toBe(1);
expect(results.stdevCount).toBe(0);
});
2 changes: 1 addition & 1 deletion packages/reassure-measure/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export type Render = (component: React.ReactElement<any>) => any;
export type Cleanup = () => void;

type Config = {
runs: number;
runs: number | 'quick-3';
warmupRuns: number;
outputFile: string;
testingLibrary?: TestingLibrary;
Expand Down
7 changes: 4 additions & 3 deletions packages/reassure-measure/src/measure-function.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { type RunResult, processRunResults } from './measure-helpers';
import { showFlagsOuputIfNeeded, writeTestStats } from './output';

interface MeasureFunctionOptions {
runs?: number;
runs?: number | 'quick-3';
warmupRuns?: number;
}

Expand All @@ -18,12 +18,13 @@ export async function measureFunction(fn: () => void, options?: MeasureFunctionO

export function measureFunctionInternal(fn: () => void, options?: MeasureFunctionOptions): MeasureResults {
const runs = options?.runs ?? config.runs;
const runCount = runs === 'quick-3' ? 3 : runs;
const warmupRuns = options?.warmupRuns ?? config.warmupRuns;

showFlagsOuputIfNeeded();

const runResults: RunResult[] = [];
for (let i = 0; i < runs + warmupRuns; i += 1) {
for (let i = 0; i < runCount + warmupRuns; i += 1) {
const timeStart = getCurrentTime();
fn();
const timeEnd = getCurrentTime();
Expand All @@ -32,7 +33,7 @@ export function measureFunctionInternal(fn: () => void, options?: MeasureFunctio
runResults.push({ duration, count: 1 });
}

return processRunResults(runResults, warmupRuns);
return processRunResults(runResults, runs, warmupRuns);
}

function getCurrentTime() {
Expand Down
7 changes: 6 additions & 1 deletion packages/reassure-measure/src/measure-helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ export interface RunResult {
count: number;
}

export function processRunResults(results: RunResult[], warmupRuns: number): MeasureResults {
export function processRunResults(results: RunResult[], runs: number | 'quick-3', warmupRuns: number): MeasureResults {
results = results.slice(warmupRuns);

results.sort((first, second) => second.duration - first.duration); // duration DESC

if (runs === 'quick-3') {
results = [results[0], results[1], results[1], results[1], results[1], results[2]];
}

const durations = results.map((result) => result.duration);
const meanDuration = math.mean(durations) as number;
const stdevDuration = math.std(...durations);
Expand Down
8 changes: 5 additions & 3 deletions packages/reassure-measure/src/measure-render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ logger.configure({
});

export interface MeasureOptions {
runs?: number;
runs?: number | 'quick-3';
warmupRuns?: number;
wrapper?: React.ComponentType<{ children: React.ReactElement }>;
scenario?: (screen: any) => Promise<any>;
Expand All @@ -27,6 +27,8 @@ export async function measurePerformance(ui: React.ReactElement, options?: Measu

export async function measureRender(ui: React.ReactElement, options?: MeasureOptions): Promise<MeasureResults> {
const runs = options?.runs ?? config.runs;
const runCount = runs === 'quick-3' ? 3 : runs;

const scenario = options?.scenario;
const warmupRuns = options?.warmupRuns ?? config.warmupRuns;

Expand All @@ -36,7 +38,7 @@ export async function measureRender(ui: React.ReactElement, options?: MeasureOpt

const runResults: RunResult[] = [];
let hasTooLateRender = false;
for (let i = 0; i < runs + warmupRuns; i += 1) {
for (let i = 0; i < runCount + warmupRuns; i += 1) {
let duration = 0;
let count = 0;
let isFinished = false;
Expand Down Expand Up @@ -72,7 +74,7 @@ export async function measureRender(ui: React.ReactElement, options?: MeasureOpt
);
}

return processRunResults(runResults, warmupRuns);
return processRunResults(runResults, runs, warmupRuns);
}

export function buildUiToRender(
Expand Down
4 changes: 3 additions & 1 deletion test-apps/native/src/OtherTest.perf-test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';
import { View, Text, Pressable } from 'react-native';
import { fireEvent, RenderAPI, screen } from '@testing-library/react-native';
import { measurePerformance } from 'reassure';
import { measurePerformance, configure } from 'reassure';

configure({ runs: 'quick-3' });

import { SlowList } from './SlowList';

Expand Down
4 changes: 3 additions & 1 deletion test-apps/native/src/SlowList.perf-test.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import * as React from 'react';
import { View, Text, Pressable } from 'react-native';
import { fireEvent, screen } from '@testing-library/react-native';
import { measurePerformance } from 'reassure';
import { measurePerformance, configure } from 'reassure';
import { SlowList } from './SlowList';

configure({ runs: 'quick-3' });

const AsyncComponent = () => {
const [count, setCount] = React.useState(0);

Expand Down
4 changes: 3 additions & 1 deletion test-apps/native/src/fib.perf-test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { measureFunction } from '@callstack/reassure-measure';
import { configure, measureFunction } from '@callstack/reassure-measure';

configure({ runs: 'quick-3' });

function fib(n: number): number {
if (n <= 1) {
Expand Down