-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Minor optimization for MergedStyle.SetStyle
#21540
base: main
Are you sure you want to change the base?
Minor optimization for MergedStyle.SetStyle
#21540
Conversation
public class StyleBenchmarker | ||
{ | ||
[Benchmark] | ||
public void MergedStyle() |
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.
This is a copy of StyleTests.StyleClassAreCorrecltyMerged
.
@@ -119,7 +119,7 @@ public void FontSizeCanBeSetFromStyle() | |||
|
|||
Assert.Equal(label.GetDefaultFontSize(), label.FontSize); | |||
|
|||
label.SetValue(Label.FontSizeProperty, 1.0, new SetterSpecificity(SetterSpecificity.StyleImplicit, 0, 0, 0)); | |||
label.SetValue(Label.FontSizeProperty, 1.0, SetterSpecificity.ImplicitSetter); |
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.
Just use the 'constants' in tests too.
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
@StephaneDelcroix Does this PR make sense to you please? |
@jonathanpeppers Does the proposed changes make sense to you please? |
ImplicitStyle?.Apply(bindable, new SetterSpecificity(SetterSpecificity.StyleImplicit, 0, 0, 0)); | ||
ImplicitStyle?.Apply(bindable, SetterSpecificity.ImplicitSetter); |
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.
So what is interesting, in your numbers on the PR description, before & after both say Allocated: 28.25 KB.
SetterSpecificity
is a struct
, and so maybe that Allocated
column is heap allocations only?
The fact the time improved, does indicate your change helps, though.
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.
SetterSpecificity
is astruct
, and so maybe thatAllocated
column is heap allocations only?
https://benchmarkdotnet.org/articles/configs/diagnosers.html#restrictions mentions:
In order to get the number of allocated bytes in cross platform way we are using GC.GetAllocatedBytesForCurrentThread which recently got exposed for netcoreapp1.1.
and GC.GetAllocatedBytesForCurrentThread
is described as follows:
The GetAllocatedBytesForCurrentThread method returns the total number of bytes allocated on the managed heap [emphasis mine] during the lifetime of a thread, not the total number of bytes that have survived garbage collection. The returned value also does not include any native allocations.
public static readonly SetterSpecificity ImplicitSetter = new(StyleImplicit, 0, 0, 0); | ||
public static readonly SetterSpecificity LocalSetter = new(StyleLocal, 0, 0, 0); | ||
public static readonly SetterSpecificity LocalClassSetter = new(StyleLocal, 0, 1, 0); |
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.
I think the main question here is if @StephaneDelcroix likes consolidating these into fields, as he is more familiar with this code. It does seem like it cleans up the code to me.
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.
Won't the reference to this field make a copy anyway? There should be no perf difference between new vs copy... Or maybe there is. No need to execute instructions, just copy memory...
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.
There might be some runtime optimization, where it is faster to copy from a field (I guess?). I'm just judging from the benchmark results. This only helps performance a small amount, so the question is if it cleans up the code. If it does, seems worth it to me.
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.
internal readonly struct SetterSpecificity : IComparable<SetterSpecificity>, IEquatable<SetterSpecificity> |
readonly
struct. I naively expected that it is not copied at all because it's a struct that does not change so it can be on heap and just accessed and not copied at all.
var buttonStyle = new Style(typeof(Button)) | ||
{ | ||
Setters = { | ||
new Setter { Property = Button.TextColorProperty, Value = Colors.Pink }, | ||
}, | ||
Class = "pink", | ||
ApplyToDerivedTypes = true, | ||
}; | ||
var labelStyle = new Style(typeof(Label)) | ||
{ | ||
Setters = { | ||
new Setter { Property = Button.BackgroundColorProperty, Value = Colors.Pink }, | ||
}, | ||
Class = "pink", | ||
ApplyToDerivedTypes = false, | ||
}; |
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.
What if the styles were created as member variables in the Benchmark class? It might narrow the work happening in the MergedStyle()
method and get us a more accurate benchmark? It will run that method many times.
If you could get the benchmark down to just merging the styles and creating the fewest objects, that would be good.
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.
I modified the benchmark to be as follows: 5dc6577 and updated OP #21540 (comment) with new numbers.
567a201
to
9683b14
Compare
9683b14
to
a950b75
Compare
Description of Change
This PR just removes a few allocations. There is no big idea.
Benchmark
MAIN
PR
Old results
Additional findings
MergedStyle.ReRegisterImplicitStyles
is not in use (at least not in this repo).maui/src/Controls/src/Core/MergedStyle.cs
Line 15 in d7dac41
Issues Fixed
Fixes #21539