Skip to content
Open
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
20 changes: 19 additions & 1 deletion benchmarks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Launch a specific test scenario with a particular configuration:
- **Method**: `start`
- **Parameters**:
- **scenario**: name of the test as defined on the `Scenario` enum in `types/testConfig.ts`
- **runType**: `instrumented|baseline|profiling`
- **runType**: one of the values defined on the `RunType` enum in `types/testConfig.ts`: `baseline|instrumented|instrumented_profiling_native`

### iOS

Expand All @@ -85,6 +85,24 @@ xcrun simctl openurl booted "benchmark://start?scenario=navigation&runType=instr
adb shell am start -W -a android.intent.action.VIEW -d 'benchmark://start?scenario=navigation\&runType=instrumented' com.benchmarkrunner
```

### Example: Profiling scenario

The profiling scenario enables native profiling when `runType` is `instrumented_profiling_native`. With `instrumented`, it only initializes the SDK.

iOS:

```
xcrun simctl openurl booted "benchmark://start?scenario=profiling&runType=instrumented_profiling_native"
```

Android:

```
adb shell am start -W -a android.intent.action.VIEW -d 'benchmark://start?scenario=profiling\&runType=instrumented_profiling_native' com.benchmarkrunner
```

Note: Native profiling only takes effect on Android 15 (API 35) and above; on lower API levels the native profiling call is a no-op.

## Stop a test scenario

Stops the scenario currently running.
Expand Down
31 changes: 31 additions & 0 deletions benchmarks/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ PODS:
- DatadogInternal (3.16.1)
- DatadogLogs (3.16.1):
- DatadogInternal (= 3.16.1)
- DatadogProfiling (3.16.1):
- DatadogInternal (= 3.16.1)
- DatadogRUM (3.16.1):
- DatadogInternal (= 3.16.1)
- DatadogSDKReactNative (3.11.0):
Expand Down Expand Up @@ -41,6 +43,29 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- DatadogSDKReactNativeProfiling (3.11.0):
- DatadogProfiling (= 3.16.1)
- DatadogSDKReactNative
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2024.11.18.00)
- RCTRequired
- RCTTypeSafety
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- DatadogSDKReactNativeSessionReplay (3.11.0):
- DatadogSDKReactNative
- DatadogSessionReplay (= 3.16.1)
Expand Down Expand Up @@ -1883,6 +1908,7 @@ PODS:
DEPENDENCIES:
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
- "DatadogSDKReactNative (from `../node_modules/@datadog/mobile-react-native`)"
- "DatadogSDKReactNativeProfiling (from `../node_modules/@datadog/mobile-react-native-profiling`)"
- "DatadogSDKReactNativeSessionReplay (from `../node_modules/@datadog/mobile-react-native-session-replay`)"
- "DatadogSDKReactNativeWebView (from `../node_modules/@datadog/mobile-react-native-webview`)"
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
Expand Down Expand Up @@ -1968,6 +1994,7 @@ SPEC REPOS:
- DatadogFlags
- DatadogInternal
- DatadogLogs
- DatadogProfiling
- DatadogRUM
- DatadogSessionReplay
- DatadogTrace
Expand All @@ -1982,6 +2009,8 @@ EXTERNAL SOURCES:
:podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec"
DatadogSDKReactNative:
:path: "../node_modules/@datadog/mobile-react-native"
DatadogSDKReactNativeProfiling:
:path: "../node_modules/@datadog/mobile-react-native-profiling"
DatadogSDKReactNativeSessionReplay:
:path: "../node_modules/@datadog/mobile-react-native-session-replay"
DatadogSDKReactNativeWebView:
Expand Down Expand Up @@ -2139,8 +2168,10 @@ SPEC CHECKSUMS:
DatadogFlags: 65cb325168aed2f7beb24ebef716227c6c2a8d1a
DatadogInternal: 152be7f0a389684161fa642e55509163c99757d5
DatadogLogs: 0c145bb072308903df8a7edd9c1125f4b479fa5f
DatadogProfiling: 03a1ac3f8fbeee901aceb5f176c2ce1918e6c826
DatadogRUM: dcffd64699184ef38f63d42bd331cc1eba967661
DatadogSDKReactNative: 71c08109f6606110d115a4371b397aefd0602e5e
DatadogSDKReactNativeProfiling: 8cb3c971d9c2e4c18ed3f86b77d20f9683a39bde
DatadogSDKReactNativeSessionReplay: dabfdd28924ab6a001e7c8aea61b40b4a483d3aa
DatadogSDKReactNativeWebView: 75353385df029f3b4f105f5b1f6cc3b822172147
DatadogSessionReplay: 137621c077cfb039224ecb3955a8d9a015d065a0
Expand Down
1 change: 1 addition & 0 deletions benchmarks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
},
"dependencies": {
"@datadog/mobile-react-native": "workspace:packages/core",
"@datadog/mobile-react-native-profiling": "workspace:packages/react-native-profiling",
"@datadog/mobile-react-native-session-replay": "workspace:packages/react-native-session-replay",
"@datadog/mobile-react-native-webview": "workspace:packages/react-native-webview",
"@datadog/mobile-react-navigation": "workspace:packages/react-navigation",
Expand Down
3 changes: 3 additions & 0 deletions benchmarks/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import TracesScenario from './scenario/Traces/tracesScenario';
import RUMManualScenario from './scenario/RUM/Manual/rumManualScenario';
import RUMAutoScenario from './scenario/RUM/Auto/rumAutoScenario';
import SessionReplayScenario from './scenario/SessionReplay/sessionReplayScenario';
import ProfilingScenario from './scenario/Profiling/profilingScenario';

function App(): React.JSX.Element {
const [testConfig, setTestConfig] = useState<TestConfig | undefined>();
Expand Down Expand Up @@ -85,6 +86,8 @@ function App(): React.JSX.Element {
return <RUMAutoScenario testConfig={testConfig}/>;
case Scenario.SessionReplay:
return <SessionReplayScenario testConfig={testConfig}/>;
case Scenario.Profiling:
return <ProfilingScenario testConfig={testConfig}/>;
// Add new scenarios here
default:
return (
Expand Down
116 changes: 116 additions & 0 deletions benchmarks/src/scenario/Profiling/profilingScenario.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
* This product includes software developed at Datadog (https://www.datadoghq.com/).
* Copyright 2016-Present Datadog, Inc.
*/

import React, { useEffect, useState } from 'react';
import {
ActivityIndicator,
Button,
Platform,
SafeAreaView,
Text,
View,
} from 'react-native';
import type { ProfilingScenarioProps } from './types';
import { DdProfiling } from '@datadog/mobile-react-native-profiling';
import { RunType } from '../../testSetup/types/testConfig';
import { instrument } from '../../testSetup/testUtils';
import {
blockJsThread,
computePrimes,
fibonacci,
sortNumbers,
} from './profilingUtils';
import { Colors, CommonStyles as styles } from '../../common/styles';

const OS = Platform.OS;
const SORT_COUNT = 1_000_000;
const FIBONACCI_N = 35;
const PRIMES_LIMIT = 1_000_000;
const LONG_TASK_DURATION_MS = 500;

function ProfilingScenario(props: ProfilingScenarioProps): React.JSX.Element {
const [isRunning, setIsRunning] = useState<boolean>(false);
const [lastResult, setLastResult] = useState<string>('');

useEffect(() => {
console.log(props.testConfig);
const runType = props.testConfig?.runType;
if (runType !== RunType.BASELINE) {
instrument().then(async () => {
if (runType === RunType.INSTRUMENTED_PROFILING_NATIVE) {
Comment on lines +42 to +43
console.log("Enabling native profiling");
await DdProfiling.enable({
applicationLaunchSampleRate: 100,
continuousSampleRate: 100,
});
Comment on lines +45 to +48
}
});
}
}, []);

const runWork = (label: string, work: () => void) => {
setIsRunning(true);
setLastResult('');

const startTime = performance.now();
work();
const durationMs = performance.now() - startTime;

setLastResult(`${label} took ${durationMs.toFixed(0)}ms`);
setIsRunning(false);
Comment on lines +58 to +63
};

const onSortNumbers = () => runWork(`Sort ${SORT_COUNT} numbers`, () => sortNumbers(SORT_COUNT));
const onFibonacci = () => runWork(`Fibonacci(${FIBONACCI_N})`, () => fibonacci(FIBONACCI_N));
const onComputePrimes = () => runWork(`Primes up to ${PRIMES_LIMIT}`, () => computePrimes(PRIMES_LIMIT));
const onLongTask = () => runWork('JS long task', () => blockJsThread(LONG_TASK_DURATION_MS));

return (
<SafeAreaView style={styles.safeAreaContainer}>
<View style={styles.container}>
<Text style={styles.title}>PROFILING SCENARIO</Text>
<View style={styles.holder}>
<View style={styles.buttonWrapper}>
<Button
color={OS === 'android' ? Colors.DatadogPurple : Colors.White}
onPress={onSortNumbers}
title="Sort numbers"
disabled={isRunning}
/>
</View>
<View style={styles.buttonWrapper}>
<Button
color={OS === 'android' ? Colors.DatadogPurple : Colors.White}
onPress={onFibonacci}
title="Fibonacci"
disabled={isRunning}
/>
</View>
<View style={styles.buttonWrapper}>
<Button
color={OS === 'android' ? Colors.DatadogPurple : Colors.White}
onPress={onComputePrimes}
title="Compute primes"
disabled={isRunning}
/>
</View>
<View style={styles.buttonWrapper}>
<Button
color={OS === 'android' ? Colors.DatadogPurple : Colors.White}
onPress={onLongTask}
title={`Trigger JS long task (${LONG_TASK_DURATION_MS}ms)`}
disabled={isRunning}
/>
</View>
</View>
{isRunning && <ActivityIndicator/>}
<Text style={styles.resultTitle}>{lastResult}</Text>
</View>
</SafeAreaView>
);
}

export default ProfilingScenario;
38 changes: 38 additions & 0 deletions benchmarks/src/scenario/Profiling/profilingUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
* This product includes software developed at Datadog (https://www.datadoghq.com/).
* Copyright 2016-Present Datadog, Inc.
*/

export const sortNumbers = (count: number): void => {
const values = Array.from({ length: count }, () => Math.random());
values.sort((a, b) => a - b);
};

export const fibonacci = (n: number): number => {
if (n < 2) {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
};

export const computePrimes = (limit: number): number => {
const isComposite = new Uint8Array(limit + 1);
let count = 0;
for (let i = 2; i <= limit; i++) {
if (!isComposite[i]) {
count++;
for (let j = i * i; j <= limit; j += i) {
isComposite[j] = 1;
}
}
}
return count;
};

export const blockJsThread = (durationMs: number): void => {
const start = Date.now();
while (Date.now() - start < durationMs) {
// no-op
}
};
11 changes: 11 additions & 0 deletions benchmarks/src/scenario/Profiling/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
* This product includes software developed at Datadog (https://www.datadoghq.com/).
* Copyright 2016-Present Datadog, Inc.
*/

import type { TestConfig } from "../../testSetup/types/testConfig"

export type ProfilingScenarioProps = {
testConfig?: TestConfig,
}
1 change: 1 addition & 0 deletions benchmarks/src/testSetup/testUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export const initializeDatadog = (clientToken?: string, environment?: string, ap
trackErrors: true,
sessionSampleRate: 100,
nativeCrashReportEnabled: true,
longTaskThresholdMs: 200,
},
logsConfiguration: {
bundleLogsWithRum: true,
Expand Down
5 changes: 3 additions & 2 deletions benchmarks/src/testSetup/types/testConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ export enum Scenario {
Traces = 'traces',
RUMManual = 'rumManual',
RUMAuto = 'rumAuto',
SessionReplay = 'sessionReplay'
SessionReplay = 'sessionReplay',
Profiling = 'profiling'
// Add new scenarios here
}

export enum RunType {
BASELINE = 'baseline',
INSTRUMENTED = 'instrumented',
PROFILING ='profiling'
INSTRUMENTED_PROFILING_NATIVE = 'instrumented_profiling_native',
};

export interface TestConfig {
Expand Down
1 change: 1 addition & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6761,6 +6761,7 @@ __metadata:
"@datadog/datadog-ci": 5.11.0
"@datadog/mobile-react-native": "workspace:packages/core"
"@datadog/mobile-react-native-babel-plugin": "workspace:packages/react-native-babel-plugin"
"@datadog/mobile-react-native-profiling": "workspace:packages/react-native-profiling"
"@datadog/mobile-react-native-session-replay": "workspace:packages/react-native-session-replay"
"@datadog/mobile-react-native-webview": "workspace:packages/react-native-webview"
"@datadog/mobile-react-navigation": "workspace:packages/react-navigation"
Expand Down
Loading