Repository: JetBrains/compose-multiplatform
File: benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/Benchmarks.kt (Kotlin)

Code before:
    onExit: () -> Unit
) {
    var currentBenchmarkIndex by remember { mutableStateOf(0) }
    if (currentBenchmarkIndex == benchmarks.size) {
        onExit()
        return
    }
    val benchmark = benchmarks[currentBenchmarkIndex]
    if (Config.isBenchmarkEnabled(benchmark.name)) {
        Box(modifier = Modifier.fillMaxSize()) {
            benchmark.content()

            LaunchedEffect(benchmark.name) {
                val start = TimeSource.Monotonic.markNow()
                val frames = MutableList(benchmark.frameCount) {
                    BenchmarkFrame(Duration.ZERO, Duration.ZERO)
                }
                repeat(benchmark.frameCount) {
                    val frameStart = TimeSource.Monotonic.markNow()
                    withFrameNanos { }
                    frames[it] = BenchmarkFrame(frameStart.elapsedNow(), Duration.ZERO)
                }
                val duration = start.elapsedNow()
                val stats = BenchmarkResult(
                    name = benchmark.name,
                    frameBudget = (1.seconds.inWholeNanoseconds / frameRate).nanoseconds,
                    conditions = BenchmarkConditions(benchmark.frameCount, 0),
                    averageFrameInfo = FrameInfo(duration / benchmark.frameCount, Duration.ZERO),
                    averageFPSInfo = FPSInfo(benchmark.frameCount.toDouble() / duration.toDouble(DurationUnit.SECONDS)),
                    frames = frames
                ).generateStats()
                stats.prettyPrint()
                if (Config.saveStats()) {
                    saveBenchmarkStats(name = benchmark.name, stats = stats)
                }
                currentBenchmarkIndex++
            }
        }
    } else {
        LaunchedEffect(benchmark.name) {
            currentBenchmarkIndex++
        }
    }
}

suspend fun runBenchmarks(
    width: Int = 1920,
    height: Int = 1080,
    targetFps: Int = 120,
    warmupCount: Int = 100,
    graphicsContext: GraphicsContext? = null

Review comment (suggestion):
Looks like `frameRate` is used only to calculate `frameBudget`.

What do you think about passing the correct `frameBudget` value in parameters and remove the calculation here?

It would make the function a bit more clear - when I saw the `frameRate` parameter first I thought the the BenchmarkRunner tries to enforce a certain frameRate.

Code after:
    onExit: () -> Unit
) {
    var currentBenchmarkIndex by remember { mutableStateOf(0) }
    if (currentBenchmarkIndex == benchmarks.size) {
        onExit()
        return
    }
    val benchmark = benchmarks[currentBenchmarkIndex]
    if (Config.isBenchmarkEnabled(benchmark.name)) {
        Box(modifier = Modifier.fillMaxSize()) {
            benchmark.content()

            LaunchedEffect(benchmark.name) {
                val start = TimeSource.Monotonic.markNow()
                val frames = MutableList(benchmark.frameCount) {
                    BenchmarkFrame(Duration.ZERO, Duration.ZERO)
                }
                repeat(benchmark.frameCount) {
                    val frameStart = TimeSource.Monotonic.markNow()
                    withFrameNanos { }
                    frames[it] = BenchmarkFrame(frameStart.elapsedNow(), Duration.ZERO)
                }
                val duration = start.elapsedNow()
                val stats = BenchmarkResult(
                    name = benchmark.name,
                    frameBudget = (1.seconds.inWholeNanoseconds / deviceFrameRate).nanoseconds,
                    conditions = BenchmarkConditions(benchmark.frameCount, 0),
                    averageFrameInfo = FrameInfo(duration / benchmark.frameCount, Duration.ZERO),
                    averageFPSInfo = FPSInfo(benchmark.frameCount.toDouble() / duration.toDouble(DurationUnit.SECONDS)),
                    frames = frames
                ).generateStats()
                stats.prettyPrint()
                if (Config.saveStats()) {
                    saveBenchmarkStats(name = benchmark.name, stats = stats)
                }
                currentBenchmarkIndex++
            }
        }
    } else {
        LaunchedEffect(benchmark.name) {
            currentBenchmarkIndex++
        }
    }
}

suspend fun runBenchmarks(
    width: Int = 1920,
    height: Int = 1080,
    targetFps: Int = 120,
    warmupCount: Int = 100,
    graphicsContext: GraphicsContext? = null