为什么没有额外分配内存

问题描述 投票:0回答:1

当我进行以下基准测试时,基准信息表明没有额外的内存分配。但是,将结构体转换为接口不涉及装箱吗?

        [MemoryDiagnoser]
        public class Test
        {
            [Benchmark]
            public Color Test123()
            {
                Color color = new Color();
                IFormattable formattable = color;
                return (Color)formattable;
            }

            [Benchmark]
            public int Test234()
            {
                int number = 114514;
                IConvertible convertible = number;
                return (int)convertible;
            }
        }
 


    [StructLayout(LayoutKind.Sequential)]
    public struct Color : IFormattable
    {
        public double R { get; set; }
        public double G { get; set; }
        public double B { get; set; }
        public double A { get; set; }

        public static Color GetRandomColor()
        {
            Random rand = new Random();
            double r = rand.Next(0, 256) * rand.NextDouble();
            double g = rand.Next(0, 256) * rand.NextDouble();
            double b = rand.Next(0, 256) * rand.NextDouble();
            double a = rand.Next(0, 256) * rand.NextDouble();

            return new Color(r, g, b, a);
        }

        public string ToString(string? format, IFormatProvider? formatProvider)
        {
            return $"{R} {G} {B} {A}";
        }

        public Color(double r, double g, double b, double a)
        {
            R = r;
            G = g;
            B = b;
            A = a;
        }
        public static bool operator ==(Color left, Color right)
        {
            return left.R == right.R && left.G == right.G && left.B == right.B && left.A == right.A;
        }

        public static bool operator !=(Color left, Color right)
        {
            return !(left == right);
        }
    }

.NET 8

结果

Color 结构仅包含四个双成员:RGBA。

“我尝试打开Rider分析IL代码,发现确实有装箱和拆箱指令。我想了解为什么没有额外的内存分配。”

  .method public hidebysig static valuetype Program.Color
    Test123() cil managed
  {
    .maxstack 1
    .locals init (
      [0] valuetype Program.Color color,
      [1] class [System.Runtime]System.IFormattable formattable,
      [2] valuetype Program.Color V_2
    )

    // [28 9 - 28 10]
    IL_0000: nop

    // [29 13 - 29 39]
    IL_0001: ldloca.s     color
    IL_0003: initobj      Program.Color

    // [30 13 - 30 46]
    IL_0009: ldloc.0      // color
    IL_000a: box          Program.Color
    IL_000f: stloc.1      // formattable

    // [31 13 - 31 39]
    IL_0010: ldloc.1      // formattable
    IL_0011: unbox.any    Program.Color
    IL_0016: stloc.2      // V_2
    IL_0017: br.s         IL_0019

    // [32 9 - 32 10]
    IL_0019: ldloc.2      // V_2
    IL_001a: ret

  } // end of method Program::Test123
c# struct cil boxing
1个回答
0
投票

JIT 编译器足够智能,可以删除

formattable
体操,并且本质上只返回
color

如果您更改方法以实际返回 IFormattable,您将获得分配:

public IFormattable Test123() {
    Color color = new Color();
    IFormattable formattable = color;
    return formattable;
}
© www.soinside.com 2019 - 2024. All rights reserved.