Context: https://github.com/dotnet/maui/issues/23991
Context: https://github.com/chabiss/periodictable
In the above sample, a lot of time is spent in:
921.46ms (4.3%) mono!Android.Graphics.Paint.Cap.get_Butt()
872.40ms (4.1%) mono!Android.Graphics.Paint.Join.get_Miter()
This exposes a performance issue with `Java.Lang.Enum` values:
* `java.lang.Enum` in Java are objects (not `int` like C#)
* When accessing an enum value, Java returns an object we have to wrap
in a C# object.
* .NET for Android has to do bookkeeping around this, lookup in a hash
table, etc.
To avoid this, we can store the `Join` and `Cap` values in a static
field and avoid calling into Java. This approach is already working
in .NET MAUI for `ImageView.ScaleType`:
9361f90a5d/src/Core/src/Platform/Android/AspectExtensions.cs (L7-L10)
After this change, the time spent is completely gone:
2.41ms (0.02%) mono.android!Android.Graphics.Paint.Join.get_Miter()
I can't find the same call for (the unfortunately named) `get_Butt()`
at all.
In the future, we might consider changing the C# binding for
`Java.Lang.Enum` to "auto-cache" values in C# static fields. Not sure
if there is enough time left for it to happen in .NET 9, though.
### Description of Change
Uses a more conservative approach of determining tablet mode on Windows.
This approach is functionally identical to [Chromium's implementation](
https://source.chromium.org/chromium/chromium/src/+/main:base/win/win_util.cc;l=537;drc=ac83a5a2d3c04763d86ce16d92f3904cc9566d3a;bpv=0;bpt=1)
for determining tablet on Windows. Additionally, it adds a few
documentation comments on the observed behavior.
I don't have a good idea on how to add a unit test for this, and it's a
bit of an implicit breaking change (some users who had tablet layouts
may have desktop layouts now), but I think that number of users affected
will be near, or at 0.
### Issues Fixed
Possibly fixes#22093
Context: https://github.com/dotnet/maui/issues/23991
@chabiss's sample app is running a lot of GCs:
[riodictablemaui] Explicit concurrent copying GC freed 933(127KB) AllocSpace objects, 31(4092KB) LOS objects, 49% free, 4423KB/8846KB, paused 1.328ms,169us total 33.513ms
[riodictablemaui] Explicit concurrent copying GC freed 722(46KB) AllocSpace objects, 0(0B) LOS objects, 49% free, 4581KB/9162KB, paused 1.856ms,170us total 14.835ms
[riodictablemaui] Explicit concurrent copying GC freed 641(43KB) AllocSpace objects, 1(108KB) LOS objects, 49% free, 4525KB/9050KB, paused 1.420ms,176us total 14.112ms
[riodictablemaui] Explicit concurrent copying GC freed 619(41KB) AllocSpace objects, 0(0B) LOS objects, 49% free, 4579KB/9158KB, paused 1.263ms,173us total 13.825ms
... many many more lines
This doesn't seem like a normal amount of GCs for a simple app like this.
Attaching Android Studio's allocation profiler, I can see a significant
amount of allocations at:
com.microsoft.maui.PlatformContentViewGroup.setHasClip()
Allocations: 35,906
Deallocations: 143
Total Count: 35,763
Shallow Size: 2,288,832
The call to `postInvalidate()` is running *a lot*, and this causes:
* A layout cycle
* `android.os.Message` to be allocated
* etc. etc.
I think we can simply check if `hasClip` has changed, and only call
`postInvalidate()` if it has.
Additionally, we can apply same change for `WrapperView.setHasShadow()`.
* WIP: Add xUnit types to avoid first-chance exceptions in tests
While debugging tests if you have the debugger set to catch *all* exceptions, you'll see a bunch of them for various xUnit types, such as:
System.MissingMethodException: 'Constructor on type 'Xunit.Sdk.InlineDataDiscoverer' not found.'
While they're harmless from a functional perspective, several of these happen when you start debugging tests.
This change re-implements the affected xUnit types as well as a custom MAUI test type to avoid the exception.
* Update xUnitCustomizations.cs
* Clean up code
Microsoft.DotNet.XHarness.CLI , Microsoft.DotNet.XHarness.TestRunners.Common , Microsoft.DotNet.XHarness.TestRunners.Xunit
From Version 9.0.0-prerelease.24379.2 -> To Version 9.0.0-prerelease.24405.1
Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
* [xaml] improve performance of `BindableProperty.TryConvert`
Context: https://github.com/davidortinau/AllTheLists
Profiling @davidortinau's app, I noticed the "Check-ins" sample felt
the slowest on Android.
One thing I noticed while scrolling:
58.46ms (0.87%) Microsoft.Maui.Controls!Microsoft.Maui.Controls.BindableProperty.TryConvert(object&)
47.96ms (0.74%) Microsoft.Maui.Controls!Microsoft.Maui.Controls.Xaml.TypeConversionExtensions.GetImplicitConversionOperator(System.Type,System.Type,System.Type)
`GetImplicitConversionOperator()` is using System.Reflection to look up
if a type has an implicit conversion operator. This is a slow operation.
I added some logging, to find out which types trigger this:
System.String -> Microsoft.Maui.Controls.ImageSource
System.Double -> System.String
System.String -> System.Double
For the first, `ImageSource`, we can add an entry to
`KnownTypeConverters`.
For the second, `System.Double -> System.String`, we can add an entry
to `SimpleConvertTypes`. I also added an entry for `System.Bool`.
Lastly, I don't think we should actually be looking up implicit
operators on built-in, primitive types like: `double`, `string`,
`bool`, etc. I added a check to skip these.
With this change in-place, `GetImplicitConversionOperator()` is no
longer called anymore in this app:
12.29ms (0.23%) Microsoft.Maui.Controls!Microsoft.Maui.Controls.BindableProperty.TryConvert(object&)
This should improve the performance of data-binding on all platforms.
This should hopefully not change any behavior and simply avoids
looking up implicit operators on types that do not contain any.
* Fix test failures
Context: https://github.com/davidortinau/AllTheLists
Profiling @davidortinau's app, I noticed the "Check-ins" sample felt
the slowest on Android.
One thing I noticed while scrolling:
44.37ms (0.48%) Microsoft.Maui!Microsoft.Maui.Platform.StrokeExtensions.UpdateMauiDrawable(Android.Views.View,Microsoft.Maui.IBorderStr
40.59ms (0.44%) Microsoft.Maui!Microsoft.Maui.Graphics.MauiDrawable..ctor(Android.Content.Context)
Where a lot of the time is actually just spent in:
54.48ms (0.59%) Microsoft.Maui!Microsoft.Maui.Platform.ContextExtensions.GetDisplayDensity(Android.Content.Context)
The `GetDisplayDensity()` method is called a lot, and it's not using
the cached value we already have!
Reading the history in 6babd4ec, there does not appear to be a reason
we *didn't* use the cached value.
With this change in place, I see instead:
7.81ms (0.12%) Microsoft.Maui!Microsoft.Maui.Platform.StrokeExtensions.UpdateMauiDrawable(Android.Views.View,Microsoft.Maui.IBorderStr
And I don't see *any* time spent in `MauiDrawable..ctor()` anymore.
This change should improve the performance of any `<Border/>` on Android.
* [Testing] Added a support for the device's theme change
* Comments resolved
* Use Adb
* UI Test improvement
* Updated test
* More snapshots
* [Testing] Added a support for the device's theme change
* Comments resolved
* Use Adb
* UI Test improvement
* Updated test
* More snapshots
* Update ThemeChange.cs
* Test fixes
* Added the first android snapshot
* Create AppThemeShouldChangeLightTheme.png
---------
Co-authored-by: Javier Suárez <javiersuarezruiz@hotmail.com>
Co-authored-by: Jonathan Dick <jodick@microsoft.com>
Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
* Fixed the issue #22042 & added a UITest
* Added snapshot
* Added a test category
* Updated a Ui test
* Update Issue22042.cs
* Added snapshots
* Fixed WIndows test
* Windows snapshot
---------
Co-authored-by: Javier Suárez <javiersuarezruiz@hotmail.com>
* Added Compatibility UITests (ported to Appium) to TestCases project
* Added tests pages
* More changes
* More changes
* More changes
* More changes
* More fixes
* More fixes
* More changes
* More changes
* More changes
* More changes
* More fixes
* Avoid problems with duplicated issues
* More changes
* More changes
* More fixes
* Fixes on Windows tests
* More fixes
* More fixes
* More changes
* Removed duplicated tests
* More fixes
* More changes
* More changes
* More changes
* More changes
* More changes
* Removed unnecessary changes
* More changes
* Ignore golden tests on macOS
* More changes
* More changes
* More changes
* Changes in AppiumLifecycleActions
* More changes
* Removed IgnoreIfPlatforms usage
* Small changes
* Fix build errors
* Fix build error
* Add missing category
* Update Issue24574.cs
* Ignore on Mac for now
---------
Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
Microsoft.DotNet.XHarness.CLI , Microsoft.DotNet.XHarness.TestRunners.Common , Microsoft.DotNet.XHarness.TestRunners.Xunit
From Version 9.0.0-prerelease.24374.1 -> To Version 9.0.0-prerelease.24379.2
Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
* Remove the 'Resources' prefix from BundleResource
Fixes#23554
Prior to Maui 8.0.70, there was a bug that only removed the "Resources/" prefix, and not the correct "Platforms/iOS/Resource": https://github.com/dotnet/maui/issues/16734
This PR https://github.com/dotnet/maui/pull/23269 fixes the original issue, but now exposed the case where BundleResource were included in the root Resources folder instead of the Platforms/iOS/ folder.
* Update Microsoft.Maui.Controls.SingleProject.targets
* Update Microsoft.Maui.Controls.SingleProject.targets
* Add a test
* string
* Fix
* Optimize
* Seek back
* Optimization
* Use Microsoft.IO.RecyclableMemoryStream
* Not needed?
* It seems I can remove version now
* Review
* Add test