Roslyn: Compiler Should Emit More Efficient IL When Involving Structs with Nullable<T> Properties

Created on 3 Oct 2018  路  6Comments  路  Source: dotnet/roslyn

Version Used: Latest in Visual Studio 15.8.6

Steps to Reproduce:

Sample code:

public class Program
{
    static void Main()
    {
        BenchmarkRunner.Run<Program>();
    }

    [Benchmark(Baseline = true)]
    public uint? Activated() => new Structure(100).SomeValue;

    [Benchmark]
    public uint? ActivatedAssignment()
    {
        var selection = new Structure(100);
        return selection.SomeValue;
    }
}

public readonly struct Structure
{
    public Structure(uint? someValue) => SomeValue = someValue;

    public uint? SomeValue { get; }
}

Expected Behavior:

Expected behavior (in my view, at least) is to use the minimal amount of code and enjoy the same performance benefits. That is, it is _generally_ intuitive (yes, there are exceptions 馃槄) to expect less code = better performance.

Actual Behavior:

In this case, it seems that less code actually leads to degraded performance, by roughly 30%.

// * Summary *

BenchmarkDotNet=v0.11.1, OS=Windows 10.0.17134.285 (1803/April2018Update/Redstone4)
Intel Core i7-4820K CPU 3.70GHz (Haswell), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=2.1.402
  [Host]     : .NET Core 2.1.4 (CoreCLR 4.6.26814.03, CoreFX 4.6.26814.02), 64bit RyuJIT
  DefaultJob : .NET Core 2.1.4 (CoreCLR 4.6.26814.03, CoreFX 4.6.26814.02), 64bit RyuJIT


              Method |     Mean |     Error |    StdDev | Scaled |
-------------------- |---------:|----------:|----------:|-------:|
           Activated | 4.700 ns | 0.0128 ns | 0.0107 ns |   1.00 |
 ActivatedAssignment | 3.331 ns | 0.0278 ns | 0.0260 ns |   0.71 |

More context and discussion around this can be found here:

https://stackoverflow.com/questions/52565479/is-activating-a-struct-without-storing-it-as-a-local-variable-expected-to-be-slo

FWIW, I am hesitant to post this here as there are already 5,000 (!) issues that you are already having to deal with currently. I didn't want to seem like I am piling on with yet another consideration. Even at 5,000 issues, I would have never known. You are doing really amazing work here! If anything please consider this for awareness and information.

Please let me know if there are any questions around this and I will do my best to answer them for you.

Area-External

All 6 comments

Why do you believe that readonly struct is part of the issue here? The IL generated is identical whether or not the struct is readonly (minus of course the emitted IsReadOnly attribute).

FWIW, I am hesitant to post this here as there are already 5,000 (!) issues that you are already having to deal with currently

Our high issue count shouldn't be a barrier to telling us about problems 馃槃 At the same time though I believe this is better suited for the coreclr repository as it appears to be a runtime issue, not a C# one.

Why do you believe that readonly struct is part of the issue here?

Gooooood point, @jaredpar. I happened to have found this while trying out the readonly struct magic and apparently conflated my ensuing performance angst with it. 馃榿 FWIW, it was suggested that I post this issue here based on the conversation with the person who answered the question on StackOverflow. Their impression was that this is a compiler issue, but I am, of course, cool with wherever you would like to send this. 馃憤

Their impression was that this is a compiler issue,

It's never a compiler bug ... except for the cases where it's a compiler bug 馃槈

In this case it looks like a runtime issue though. The IL here is correct in both cases and logically equivalent. Weird that they would optimize one case better than the other.

I do have to admit I am a bit out of my element here. When you say coreclr/runtime, are you saying/suggesting that this is JIT-related, by chance? I am trying to rectify the difference here of basically being told the opposite of what the answer on StackOverflow was. Not that I should doubt you, of course. You do work on the thing, after all. 馃槅

Again, this is not my area of expertise so please forgive my confusion here. I am simply trying to assuage it and be a better-informed citizen.

Again, this is not my area of expertise so please forgive my confusion here.

No worries. Performance is often confusing. Particularly in complex systems.

I am trying to rectify the difference here of basically being told the opposite of what the answer on StackOverflow was.

The part of the analysis which blames C# is wrong. I will follow up.

Awesome. Thank you so much @jaredpar for taking some time to help a perf newb out. I really appreciate it and it means a lot to me, 5,000 issues strong. 馃槀

Was this page helpful?
0 / 5 - 0 ratings