Skip to content
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

Optimize type check efficiency with .IsValueType #82305

Closed
wants to merge 1 commit into from

Conversation

Bojun-Feng
Copy link

@Bojun-Feng Bojun-Feng commented Feb 17, 2023

What

This pull request replaces cases of default(T) != null with typeof(T).IsValueType for better assembly performance, as mentioned in #82291.

Effect

Before
Before

After
After

This is my first time contributing to open source projects. Please let me know if there are any formatting issues.

Fix #82291

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Feb 17, 2023
@ghost ghost added the community-contribution Indicates that the PR has been added by a community member label Feb 17, 2023
@dnfadmin
Copy link

dnfadmin commented Feb 17, 2023

CLA assistant check
All CLA requirements met.

@ghost
Copy link

ghost commented Feb 17, 2023

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch, @kunalspathak
See info in area-owners.md if you want to be subscribed.

Issue Details

This pull request replaces cases of default(T) != null with typeof(T).IsValueType for better assembly performance.

Before
Before

After
After

Fix #82291

Author: Bojun-Feng
Assignees: -
Labels:

area-CodeGen-coreclr

Milestone: -

@@ -1742,7 +1742,7 @@ protected override sealed bool ItemsMustBeUnique

protected override sealed bool ItemsMustBeNonNull
{
get { return default(T) != null; }
get { return typeof(T).IsValueType; }
Copy link
Member

Choose a reason for hiding this comment

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

This is a test; it doesn't need to be changed.

@@ -19,7 +19,7 @@ internal static bool IsValueType<T>()
#if NETCOREAPP
return typeof(T).IsValueType;
#else
if (default(T) != null)
if (typeof(T).IsValueType)
Copy link
Member

Choose a reason for hiding this comment

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

This is a downlevel path. This may be used in runtimes where typeof(T).IsValueType isn't an intrinsic and isn't optimized. Note that this is part of an #else where the #if NETCOREAPP already uses IsValueType.

@@ -78,7 +78,7 @@ public void Comparer_IComparerCompareWithObjectsNotOfMatchingTypeShouldThrow()
// throw if both inputs are non-null and one of them is not of type T
IComparer comparer = Comparer<T>.Default;
StrongBox<T> notOfTypeT = new StrongBox<T>(default(T));
if (default(T) != null) // if default(T) is null these asserts will fail as IComparer.Compare returns early if either side is null
if (typeof(T).IsValueType) // if default(T) is null these asserts will fail as IComparer.Compare returns early if either side is null
Copy link
Member

Choose a reason for hiding this comment

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

This is a test and doesn't need to be changed. (The comment would also be stale if it were changed.)

@@ -85,7 +85,7 @@ public void EqualityComparer_IEqualityComparerEqualsWithObjectsNotOfMatchingType
Assert.Equal(default(T) == null, comparer.Equals(null, default(T)));
Assert.True(comparer.Equals(null, null));

if (default(T) != null) // if default(T) is null this assert will fail as IEqualityComparer.Equals returns early if either input is null
if (typeof(T).IsValueType) // if default(T) is null this assert will fail as IEqualityComparer.Equals returns early if either input is null
Copy link
Member

Choose a reason for hiding this comment

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

This is a test and doesn't need to be changed.

@@ -451,7 +451,7 @@ private static bool IsCompatibleObject(object? value)

private static void ValidateNullValue(object? value, string argument)
{
if (value == null && default(T) != null)
if (value == null && typeof(T).IsValueType)
Copy link
Member

Choose a reason for hiding this comment

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

This will be wrong for Nullable<T>, e.g. if value is null and typeof(T) is typeof(int?), then the code previously wouldn't have thrown but now it will.

@@ -31,7 +31,7 @@ internal static class AggregationMinMaxHelpers<T>

AssociativeAggregationOperator<T, Pair<bool, T>, T> aggregation =
new AssociativeAggregationOperator<T, Pair<bool, T>, T>(source, new Pair<bool, T>(false, default!), null,
true, intermediateReduce, finalReduce, resultSelector, default(T) != null, QueryAggregationOptions.AssociativeCommutative);
true, intermediateReduce, finalReduce, resultSelector, typeof(T).IsValueType, QueryAggregationOptions.AssociativeCommutative);
Copy link
Member

Choose a reason for hiding this comment

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

Same Nullable<T> concern

@@ -232,7 +232,7 @@ public static unsafe void Fill<T>(ref T refData, nuint numElements, T value)

nint index = 0; // Use nint for arithmetic to avoid unnecessary 64->32->64 truncations

if (default(T) != null || (object?)value != null)
Copy link
Member

@stephentoub stephentoub Feb 17, 2023

Choose a reason for hiding this comment

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

Do these changes really have a material impact on the codegen? I wouldn't expect them to. The before/after in the opening post where there's poorer code gen isn't for this case.

@stephentoub
Copy link
Member

Fix 82291

Thanks for your interest in contributing! This doesn't actually fix that issue, though. That issue is about code generated by the JIT in certain cases; whether or not we use those patterns in our own code, others might use them as well, so the fix there is actually in the JIT.

@Bojun-Feng
Copy link
Author

Thanks for your interest in contributing! This doesn't actually fix that issue, though.

Thank you for the quick feedback! That makes a lot of sense.

At this point, would you say it is best to close this pull request?

@stephentoub
Copy link
Member

At this point, would you say it is best to close this pull request?

I think so. But as I said, thank you for your interest in contributing, and we'd welcome other contributions in the future if you're interested.

@Bojun-Feng
Copy link
Author

Thank you again for your patience. This is a great community.

I saw the help-wanted tag and expected it to be an easy fix, but I guess I would need to first reach a deep understanding of the codebase. I will definitely keep an eye on other help-wanted issues and put more thought into my contributions.

Issue closed.

@Bojun-Feng Bojun-Feng closed this Feb 17, 2023
@Bojun-Feng Bojun-Feng deleted the fix-82291 branch February 17, 2023 17:01
@ghost ghost locked as resolved and limited conversation to collaborators Mar 19, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI 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.

Strange boxing deopt
3 participants