在 C# 中解构元组的性能损失?

Sup*_*Bob 5 c# performance types .net-core valuetuple

如果我们这样做

var (hello, world) = GetHelloAndWorldStrings();
if (hello == "hello" && world == "world")
  Environment.Exit(0);
Run Code Online (Sandbox Code Playgroud)

除了仅执行以下操作外,这是否会产生任何额外费用:

var helloAndWorld = GetHelloAndWorldStrings();
if (helloAndWorld.Hello == "hello" && helloAndWorld.World == "world")
  Environment.Exit(0);
Run Code Online (Sandbox Code Playgroud)

或者这都是语法糖 - 最终生成的代码总是使用 Item1 和 Item2。

AAA*_*ddd 7

他们有效地产生相同的IL只有轻微发出的差异,但是......他们很可能会被即时编译和优化,正是相同的指令。

给定的

private (String hello,string world) GetHelloAndWorldStrings() 
{ 
   return ("asdsd","sadfsdf");
}
    
...
        

public int Test1()
{
   var asd = GetHelloAndWorldStrings();
   if (asd.hello == "hello" && asd.world == "world")
      return 1;
   return 0;
}

public int Test2()
{
   var (hello, world) = GetHelloAndWorldStrings();
   if (hello == "hello" && world == "world")
      return 1;
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

基本上会被发射

public int Test1()
{
    ValueTuple<string, string> helloAndWorldStrings = GetHelloAndWorldStrings();
    if (helloAndWorldStrings.Item1 == "hello" && helloAndWorldStrings.Item2 == "world")
    {
        return 1;
    }
    return 0;
}

public int Test2()
{
    ValueTuple<string, string> helloAndWorldStrings = GetHelloAndWorldStrings();
    string item = helloAndWorldStrings.Item1;
    string item2 = helloAndWorldStrings.Item2;
    if (item == "hello" && item2 == "world")
    {
        return 1;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

您可以在此处查看 IL

这是发布中的JIT ASM示例

C.Test1()
    L0000: push ebp
    L0001: mov ebp, esp
    L0003: push esi
    L0004: mov ecx, [0x11198648]
    L000a: mov esi, [0x1119864c]
    L0010: mov edx, [0x11198650]
    L0016: call System.String.Equals(System.String, System.String)
    L001b: test eax, eax
    L001d: je short L0038
    L001f: mov edx, [0x11198654]
    L0025: mov ecx, esi
    L0027: call System.String.Equals(System.String, System.String)
    L002c: test eax, eax
    L002e: je short L0038
    L0030: mov eax, 1
    L0035: pop esi
    L0036: pop ebp
    L0037: ret
    L0038: xor eax, eax
    L003a: pop esi
    L003b: pop ebp
    L003c: ret
Run Code Online (Sandbox Code Playgroud)

对比

C.Test2()
    L0000: push ebp
    L0001: mov ebp, esp
    L0003: push esi
    L0004: mov ecx, [0x11198648]
    L000a: mov esi, [0x1119864c]
    L0010: mov edx, [0x11198650]
    L0016: call System.String.Equals(System.String, System.String)
    L001b: test eax, eax
    L001d: je short L0038
    L001f: mov edx, [0x11198654]
    L0025: mov ecx, esi
    L0027: call System.String.Equals(System.String, System.String)
    L002c: test eax, eax
    L002e: je short L0038
    L0030: mov eax, 1
    L0035: pop esi
    L0036: pop ebp
    L0037: ret
    L0038: xor eax, eax
    L003a: pop esi
    L003b: pop ebp
    L003c: ret
Run Code Online (Sandbox Code Playgroud)

简而言之,担心这个的净收益……减去你生命中的 5 分钟,你将永远不会回来