-
Notifications
You must be signed in to change notification settings - Fork 4.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
Expand unboxing for Nullable<> in JIT #105073
Conversation
@EgorBot -intel -arm64 using BenchmarkDotNet.Attributes;
public class MyBench
{
[Benchmark]
[Arguments(42)]
[Arguments(null)]
public int? Unbox(object o) => (int?)o;
} |
Does it worth to recognize Or, can we write the method in C# and make helpers inlinable? This will help more around nullables. |
Yes, that is an option, requires some effort to make helpers inlineable, they're currently not. I decided to do it in JIT since the actual change is like 30 LOC, the rest are comments. If we move it to an inlineable helper we can delete this I guess.. |
Benchmark results on Intel
|
Benchmark results on Arm64
|
@jakobbotsch @AndyAyersMS cc @dotnet/jit-contrib PTAL, the actual change is 40 LOC, benchmarks attached. Jit-diff: MihuBot/runtime-utils#541 obviously, a size regression, but there were also a few cases where jit can now fold the |
// Unbox the object to the result local: | ||
// | ||
// result._hasValue = true; | ||
// result._value = MethodTableLookup(obj); |
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.
oops, wrong comment, it's obj->RawData
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.
Would it be worth limiting this to relatively small types, since will create both a zeroing and a copy?
Might be a good idea to limit it, yeah @EgorBot -intel -arm64 using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
public class MyBench2
{
[InlineArray(100)]
public struct LargeStruct
{
public long Fld;
}
[Benchmark]
[Arguments(42)]
[Arguments(null)]
public LargeStruct? Unbox(object o) => (LargeStruct?)o;
} |
Benchmark results on Intel
|
@EgorBot -intel -arm64 using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
public class MyBench2
{
[InlineArray(100)]
public struct LargeStruct
{
public long Fld;
}
public IEnumerable<object> TestData()
{
yield return null;
yield return new LargeStruct();
}
[Benchmark]
[ArgumentsSource(nameof(TestData))]
public LargeStruct? Unbox(object o) => (LargeStruct?)o;
} |
Benchmark results on Intel
|
Benchmark results on Arm64
|
Closes #104954
Currently, unboxing for Nullable<> always go through a helper call, while we can inline it in JIT.
Current codegen:
New codegen:
Benchmark: