Skip to content

Conversation

xtqqczze
Copy link
Contributor

@xtqqczze xtqqczze commented Aug 4, 2025

Avoid handling the null case when the variable is known not be null.

MihuBot/runtime-utils#1346

@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Aug 4, 2025
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-text-encoding
See info in area-owners.md if you want to be subscribed.

@tarekgh
Copy link
Member

tarekgh commented Aug 4, 2025

@xtqqczze is this a blocker to .NET 10? The bar now is a little bit higher and if this is not a blocker we can delay this to the next release.

CC @MihaZupan

@MihaZupan
Copy link
Member

Definitely not a blocker for 10

@tarekgh tarekgh marked this pull request as draft August 4, 2025 18:40
@tarekgh
Copy link
Member

tarekgh commented Aug 4, 2025

I have converted the PR to be draft till the main will be open for .NET 11 changes. Thanks!

@xtqqczze
Copy link
Contributor Author

Ready for review now main is open for .NET 11 changes.

Copy link
Member

@tarekgh tarekgh left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks.

Cc @stephentoub @jkotas in case they are interested in taking a quick look.

@@ -93,7 +93,7 @@ public override unsafe int GetByteCount(char[] chars, int index, int count)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.chars, ExceptionResource.ArgumentOutOfRange_IndexCountBuffer);
}

fixed (char* pChars = chars)
fixed (char* pChars = &MemoryMarshal.GetArrayDataReference(chars))
Copy link
Member

Choose a reason for hiding this comment

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

We're trying to reduce the amount of unsafe logic in the core libraries, these types of micro-optimizations aren't really something I think we want to take.

It'd rather be better for the JIT to be able to avoid or elide any additional cost here from the GetPinnableReference logic in the case it knows chars is non-null.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

@jkotas jkotas Aug 19, 2025

Choose a reason for hiding this comment

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

This is unsafe code both before and after this change. We use MemoryMarshal.GetArrayDataReference and GetPinnableReference micro-optimizations in many places, so I do not see a problem with using it in a few more places.

It'd rather be better for the JIT to be able to avoid or elide any additional cost here from the GetPinnableReference logic in the case it knows chars is non-null.

The JIT does that where possible. "Avoid handling the null case when the variable is known not be null." is not accurate description for majority of the codediff deltas. (There are a few places where it is impossible for the JIT to prove that the null case is unreachable, but these are just a small part of the delta.)

Majority of the codediff deltas are caused by pinning byref instead of object. Before this change, the code pinned object that is a bit more code and a bit friendlier to the GC. After this change, the code pins byref that is a bit less code and a bit less friendly to the GC.

Copy link
Member

Choose a reason for hiding this comment

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

I do not see a problem with using it in a few more places.

Having said that, I agree that these micro-optimizations add clutter, and the benefit is non-measurable in most cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.Text.Encoding community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants