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

Fix playback of videos in Gallery. #4313

Merged
merged 3 commits into from
Dec 4, 2023
Merged

Fix playback of videos in Gallery. #4313

merged 3 commits into from
Dec 4, 2023

Conversation

dbrant
Copy link
Member

@dbrant dbrant commented Dec 1, 2023

Video playback is currently broken.
This is because our logic for selecting the best possible derivative for playback was not smart enough, and was blindly selecting the "last" derivative.
The list of derivatives can change, and indeed it has changed to include an unplayable derivative as the "last" one.
This improves the logic of selecting the proper derivative.

https://phabricator.wikimedia.org/T352315

@dbrant dbrant added Minor Minor stuff High Priority Priority code review needed labels Dec 1, 2023
@@ -46,16 +46,25 @@ class ImageInfo {
val width = 0
val height = 0

val bestDerivative get() = derivatives.lastOrNull()
fun getBestDerivativeForSize(widthDp: Int): Derivative? {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we add @Suppress("KotlinConstantConditions") for this function?

Copy link
Member Author

Choose a reason for hiding this comment

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

of course!

Comment on lines 51 to 57
derivatives.forEach {
if (it.width > 0 && it.width < widthDp) {
if (derivative == null || it.width > derivative!!.width) {
derivative = it
}
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it be better to use filter and mayByOrNull?

derivatives.filter { it.width < widthDp && it.width < widthDp }.maxByOrNull { it.width }

I tried a couple of times and it looks like using filter and maxByOrNull can mostly improve the efficiency

forEach                581.093us
filter+mayByOrNull     53.75us

forEach                62.032us
filter+mayByOrNull     67.604us

forEach                51.51us
filter+mayByOrNull     50.781us

forEach                118.489us
filter+mayByOrNull     57.239us

Copy link
Member Author

@dbrant dbrant Dec 2, 2023

Choose a reason for hiding this comment

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

😄 An interesting place to look for optimizations! This code won't be running thousands of times per second; it will run maybe once or twice per session. But I like the attention to detail.

However, I'm not sure I agree with the performance assessment. Here are some thoughts:

  • Did you run your measurement in Debug mode or Release mode? This kind of performance profiling must be done in Release mode to have any kind of meaning. When I run it in Release mode, my forEach method is much faster than filter+maxByOrNull.

  • To get a true sense of the performance of a loop like this, it needs to be measured over a billion iterations, not just a couple of times. There are all kinds of events happening in the VM that can throw off a single measurement of a loop.

  • The filter and maxByNull functions are not O(1). They both have their own performance costs. If you look at the actual source code of the filter function and the maxByOrNull function, they are literally using for loops to do the filtering. So, if we use filter+maxByOrNull, we would be running two loops instead of one, and also instantiating an unnecessary ArrayList (returned by filter and passed to maxByOrNull). This is guaranteed to be slower than a single forEach loop. So basically, it would be O(2n) + allocation, while my method is just O(n).

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks for the information, that explains the benefit of using the original logic you put in the code! I checked the library and you are correct!

@cooltey cooltey merged commit 8c3ec53 into main Dec 4, 2023
1 check passed
@cooltey cooltey deleted the fixVideo branch December 4, 2023 16:58
cooltey added a commit that referenced this pull request Dec 6, 2023
…esign

* origin/nearby_design:
  Bump versionCode. (#4318)
  Further fix video playback! (#4317)
  Bump versionCode. (#4316)
  Fix: make sure getting the coordinates from the page/summary endpoint (#4311)
  Fix playback of videos in Gallery. (#4313)
  Fix strings.
  Localisation updates from https://translatewiki.net.
  Revert "Fix playback of videos."
  Fix playback of videos.
  Fix: scrolling issue in the AddTemplateActivity (#4312)
  Localisation updates from https://translatewiki.net. (#4310)
  Update maplibre versions (#4306)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
High Priority Priority code review needed Minor Minor stuff
Development

Successfully merging this pull request may close these issues.

2 participants