-
Notifications
You must be signed in to change notification settings - Fork 1.9k
[android] improve FormattedString performance #21712
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
Conversation
Context: https://github.com/Redth/MauiCollectionViewGallery Fixes: #14222 This will conflict with: * #20352 But I will rework this after it is merged. Profiling the above sample while scrolling on a Pixel 5, a lot of time is spent in `FormattedStringExtensions.RecalculateSpanPositions()`: (20%) Microsoft.Maui.Controls!Microsoft.Maui.Controls.Platform.FormattedStringExtensions.RecalculateSpanPositions(Android.Widget.TextView,Microsoft.Maui.Controls.Label,Android.Text.SpannableString,Microsoft.Maui.SizeRequest) (11%) Microsoft.Maui.Controls!Microsoft.Maui.Controls.Platform.FormattedStringExtensions.FontSpan.UpdateDrawState(Android.Text.TextPaint) (11%) Microsoft.Maui.Controls!Microsoft.Maui.Controls.Platform.FormattedStringExtensions.FontSpan.Apply(Android.Text.TextPaint) (6.3%) MauiCollectionViewGallery!PoolMathApp.Helpers.FormattedTextExtensions.ToFormattedString(PoolMathApp.Models.FormattedTex The key contributors are `FontSpan` and `LineHeightSpan` which: * Implement `MetricAffectingSpan`, an abstract class that allows to change the metrics of the text. * Implement `UpdateDrawState()` and `Apply()` methods that are called during draw. Causing frequent Java -> C# interop. To fix this, let's move the following types from C# to Java: * `FontSpan` -> `PlatformFontSpan` * `LetterSpacingSpan` -> `PlatformFontSpan` (use different ctor) * `LineHeightSpan` -> `PlatformLineHeightSpan` `PlatformLineHeightSpan` is similar, as it is an implementation of the `LineHeightSpan` interface. With these changes, I see a nice improvement while scrolling: (5.5%) Microsoft.Maui.Controls!Microsoft.Maui.Controls.Platform.FormattedStringExtensions.RecalculateSpanPositions(Android.Widget.TextView,Microsoft.Maui.Controls.Label,Android.Text.SpannableString,Microsoft.Maui.SizeRequest) (4.0%) MauiCollectionViewGallery!PoolMathApp.Helpers.FormattedTextExtensions.ToFormattedString(PoolMathApp.Models.FormattedText `RecalculateSpanPositions` overall, went from 20% to 5.5%! Comparing the new types, the times spent calling the constructors are also improved: Before: (1.1%) Microsoft.Maui.Controls!Microsoft.Maui.Controls.Platform.FormattedStringExtensions.FontSpan..ctor(Microsoft.Maui.Font,M (1.5%) Microsoft.Maui.Controls!Microsoft.Maui.Controls.Platform.FormattedStringExtensions.LetterSpacingSpan..ctor(double) After: (1.0%) Microsoft.Maui!Microsoft.Maui.PlatformFontSpan..ctor(Android.Content.Context,Android.Graphics.Typeface,bool,single) (0.82%) Microsoft.Maui!Microsoft.Maui.PlatformFontSpan..ctor(single) This should be reasonable for .NET 8servicing, as there should be no behavior changes and no API changes. In a future PR, it looks like `FormattedStringExtensions` could be improved further, but this is a decent starting point that makes it a lot better.
/azp run |
Azure Pipelines could not run because the pipeline triggers exclude this branch/path. |
/azp run MAUI-UITests-public |
Azure Pipelines could not run because the pipeline triggers exclude this branch/path. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At some point, this whole method can go into Java code. We can pass in all the values as some sort of parameter list and then no interop at all.
Seeing an odd exception with MAUI 8.0.21 on Android 13. Not seeing this on Android 14. Seems maybe related to your changes here?
|
@mfeingol did you already try a rebuild? If I download: I see the file inside: So you might also check your NuGet cache, to see if something inside is malformed. |
@jonathanpeppers: okay, yeah, I had to do some cleanup but now it's working without issues so it was probably a bad build artifact. Sorry for the noise! |
Context: https://github.com/Redth/MauiCollectionViewGallery
Fixes #14222
This depends on changes in:
(as both of these would conflict with each other)
Profiling the above sample while scrolling on a Pixel 5, a lot of time is spent in
FormattedStringExtensions.RecalculateSpanPositions()
:The key contributors are
FontSpan
andLineHeightSpan
which:Implement
MetricAffectingSpan
, an abstract class that allows to change the metrics of the text.Implement
UpdateDrawState()
andApply()
methods that are called during draw. Causing frequent Java -> C# interop.To fix this, let's move the following types from C# to Java:
FontSpan
->PlatformFontSpan
LetterSpacingSpan
->PlatformFontSpan
(use different ctor)LineHeightSpan
->PlatformLineHeightSpan
PlatformLineHeightSpan
is similar, as it is an implementation of theLineHeightSpan
interface.With these changes, I see a nice improvement while scrolling:
RecalculateSpanPositions
overall, went from 20% to 5.5%!Comparing the new types, the times spent calling the constructors are also improved:
This should be reasonable for .NET 8servicing, as there should be no behavior changes and no API changes.
In a future PR, it looks like
FormattedStringExtensions
could be improved further, but this is a decent starting point that makes it a lot better.