Skip to content

Add K/Wasm D8 target to the benchmarks #5277

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

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open

Conversation

eymar
Copy link
Member

@eymar eymar commented Apr 10, 2025

  • Updated the README.md with the description of benchmarks (might be useful to external parties)
  • customized a runner for D8
  • added a warmupCount parameter to runBenchmarks, because it's required for Jetstream3 (a set of benchmarks) that there is no warmup (they skip it)
  • Added a smooth scroll variant of LazyGrid + variants with LaunchedEffect in grid cells for coroutines usage.

Fixes https://youtrack.jetbrains.com/issue/CMP-6942

Note: it's based on this PR #5275

Testing

Manually run the benchmarks

Release Notes

N/A

eymar added 6 commits April 9, 2025 14:53
…rk in preparation for D8 benchmarks

D8 environment misses some APIs including a parser of xml.

Also, make sure the web targets process the asynchronous fetch resources operations by yielding the event loop. Otherwise, a benchmark would skip a part of the workload.
@eymar eymar requested a review from pjBooms April 10, 2025 15:21
val args = "benchmarks=$benchmarkName($frameCount)"
Args.parseArgs(arrayOf(args))
Args.enableModes(Mode.SIMPLE)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use parseArgs with custom args there is no need to introduce enableModes, you may pass modes to parseArgs

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned in one of the other comments:

I realized that in a case of fun customLaunch(benchmarkName: String, frameCount: Int): Promise<JsAny?> { I'd like to minimize the strings manipulation / string building, to minimize the constant time of the benchmark.

Also it would help with avoiding a bit redundant args string parsing.

@@ -38,6 +40,8 @@ object Args {
* with values separated by commas.
*/
fun parseArgs(args: Array<String>) {
// reset the previous configuration before setting a new one for cases when parseArgs is called more than once:
reset()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would call reset explicitly from the places where it is really required.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -55,12 +59,28 @@ object Args {

private fun String.decodeArg() = replace("%20", " ")

private fun reset() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please comment this function providing reasoning when it is required

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

val itemCount = 12000
val entries = remember {List(itemCount) { Entry("$it") }}
val state = rememberLazyGridState()

var smoothScroll by remember { mutableStateOf(false)}
var scrollIteration by remember { mutableStateOf(0) }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this extra state?

Copy link
Member Author

@eymar eymar Apr 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the state.scrollToItem(curItem) won't be cancelled before it completes.

When LaunchedEffect takes curItem as a key it will be cancelled after curItem value changes.

Now, scrollIteration is a new key for LaunchedEffect.

https://developer.android.com/develop/ui/compose/side-effects#launchedeffect

If LaunchedEffect is recomposed with different keys (see the Restarting Effects section below), the existing coroutine will be cancelled and the new suspend function will be launched in a new coroutine.

val urlParams = URLSearchParams(window.location.search.toJsString())
var i = 0
val args = generateSequence { urlParams.get("arg${i++}") }.toList().toTypedArray()
Args.parseArgs(args)

Args.enableModes(Mode.SIMPLE)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User can set required modes themselves, I do not think we need to restrict them here without a strong reason (like for D8)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed Args.enableModes(Mode.SIMPLE) for browser case - fixed.

// Some targets can't support all the benchmarks (e.g. D8) due to limited APIs availability,
// so we skip them
fun skipBenchmark(benchmark: String) {
benchmarksToSkip.add(benchmark.uppercase())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename to disableBenchmark ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Args.parseArgs(args.split(" ").toTypedArray())
}
Args.enableModes(Mode.SIMPLE)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leave a comment why only Simple mode is supported (and again you can pass mode to args)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and again you can pass mode to args

I realized that in a case of fun customLaunch(benchmarkName: String, frameCount: Int): Promise<JsAny?> { I'd like to minimize the strings manipulation / string building, to minimize the constant time of the benchmark.

In this case there is no need to build the args string, because there is only one specific benchmark to run with known frameCount. The mode is also known - it's always SIMPLE for D8 (i'll add the comment to explain why it's the case).

I'll add a new function to Args: fun addBenchmark(name: String, frameCount: Int) so no parsing would be needed.

Let me know what you think

@@ -38,7 +38,7 @@ fun AnimatedVisibility() {
AnimatedVisibility(showImage) {
transition = this.transition
Image(
painterResource(Res.drawable.compose_multiplatform),
painterResource(Res.drawable.img),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess compose_multiplatform.xml is not used anymore and can be removed from the resources (and thus we can name png as compose_multiplatform.png).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants