[ios] avoid duplicating CALayer.Sublayer arrays#21308
Merged
rmarinho merged 1 commit intodotnet:mainfrom Mar 19, 2024
Merged
Conversation
In a customer's application, they saw in Xcode's Instruments:
4.4% Microsoft_Maui_Platform_StokeExtensions_UpdateBackgroundLayer_CoreAnimation_CALayer_CoreGraphics_CGRect
> 2.7% CoreAnimation_CALayer_get_Sublayers
Reviewing the code, there is a performance problem:
if (layer != null && layer.Sublayers != null)
{
foreach (var sublayer in layer.Sublayers)
{
//...
}
}
This accesses `CALayer.Sublayers` twice:
1. null check
2. `foreach`
When C# calls into Objective-C here, the returned array is marshaled
and copied to a C# array that can be consumed in managed code. We are
doing this work twice!
I audited all calls to `CALayer.Sublayers` and found that we can avoid
this in places that are called frequently.
This should improve the performance of all views on iOS or Catalyst.
However, I don't have access to the customer's application to test the
difference. We can have them try a nightly MAUI build after this is
merged.
rmarinho
approved these changes
Mar 19, 2024
jonathanpeppers
added a commit
that referenced
this pull request
Apr 10, 2024
Context: #21580 Similar to: #21308 Recording this app in `dotnet-trace`, I saw: (0.81%) Microsoft.MacCatalyst!UIKit.UIView.get_Subviews() Where this time is spent in: * `Microsoft.Maui!Microsoft.Maui.Platform.WrapperView` Reviewing the code, it calls `this.Subviews` twice, which would marshal and create two arrays. It then calls `Subviews[0]`. Storing in a local instead will avoid creating the array twice: var subviews = Subviews; if (subviews.Length == 0) return; //... var child = subviews[0]; This improves things a small amount, but is probably worth it: (0.72%) Microsoft.MacCatalyst!UIKit.UIView.get_Subviews() I'll think about making an analyzer for this, but I didn't find any similar cases that appear in `dotnet-trace` at the moment. This doesn't fully solve #21580, but it's a small improvement.
rmarinho
pushed a commit
that referenced
this pull request
Apr 11, 2024
Context: #21580 Similar to: #21308 Recording this app in `dotnet-trace`, I saw: (0.81%) Microsoft.MacCatalyst!UIKit.UIView.get_Subviews() Where this time is spent in: * `Microsoft.Maui!Microsoft.Maui.Platform.WrapperView` Reviewing the code, it calls `this.Subviews` twice, which would marshal and create two arrays. It then calls `Subviews[0]`. Storing in a local instead will avoid creating the array twice: var subviews = Subviews; if (subviews.Length == 0) return; //... var child = subviews[0]; This improves things a small amount, but is probably worth it: (0.72%) Microsoft.MacCatalyst!UIKit.UIView.get_Subviews() I'll think about making an analyzer for this, but I didn't find any similar cases that appear in `dotnet-trace` at the moment. This doesn't fully solve #21580, but it's a small improvement.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context: https://discord.com/channels/732297728826277939/732297808148824115/1219383992067821608
In a customer's application, they saw in Xcode's Instruments:
Reviewing the code, there is a performance problem:
This accesses
CALayer.Sublayerstwice:null check
foreachWhen C# calls into Objective-C here, the returned array is marshaled and copied to a C# array that can be consumed in managed code. We are doing this work twice!
I audited all calls to
CALayer.Sublayersand found that we can avoid this in places that are called frequently.This should improve the performance of all views on iOS or Catalyst. However, I don't have access to the customer's application to test the difference. We can have them try a nightly MAUI build after this is merged.