gpt4 book ai didi

c# - 具有绝对返回路径的方法如何内联?

转载 作者:太空狗 更新时间:2023-10-29 21:09:57 27 4
gpt4 key购买 nike

我主要使用 C# 开发,但我认为这个问题可能也适用于其他语言。
此外,这里似乎有很多代码,但问题很简单。

据我所知,内联是编译器(在 C# 虚拟机的情况下)通过在调用方法的每个地方插入方法主体来替换方法调用。

假设我有以下程序:

static Main()
{
int number = 7;
bool a;
a = IsEven(number);
Console.WriteLine(a);
}

...方法IsEven的主体:

bool IsEven(int n) 
{
if (n % 2 == 0) // Two conditional return paths
return true;
else
return false;
}

我可以理解内联方法后代码的样子:

static Main()
{
int number = 7;
bool a;
if (number % 2 == 0)
a = true;
else
a = false;
Console.WriteLine(a); // Will print true if 'number' is even, otherwise false
}

一个明显简单且正确的程序。

但是如果我稍微调整 IsEven 的主体以包含绝对返回路径...

bool IsEven(int n)
{
if (n % 2 == 0)
return true;
return false; // <- Absolute return path!
}

在某些情况下,我个人更喜欢这种风格。一些折射工具甚至可能会建议我将第一个版本更改为看起来像这个 - 但是当我试图想象这个方法被内联时会是什么样子时,我被难住了。
如果我们内联该方法的第二个版本:

static Main()
{
int number = 7;
bool a;
if (number % 2 == 0)
a = true;
a = false;
Console.WriteLine(a); // Will always print false!
}

要问的问题:
编译器/虚拟机如何处理内联具有绝对返回路径的方法?
这样的事情似乎极不可能真正阻止方法内联,所以我想知道如何处理这些事情。也许内联的过程不是这么简单?也许一个版本更有可能被 VM 内联?

编辑:对这两种方法(以及第一种方法的手动内联)进行分析表明在性能上没有差异,因此我只能假设这两种方法都被内联并且以相同或相似的方式工作(至少在我的 VM 上)。
此外,这些方法非常简单并且看起来几乎可以互换,但是具有绝对返回路径的复杂方法可能更难更改为没有绝对返回路径的版本。

最佳答案

很难解释 JITter 在内联时做了什么——它不会改变 C# 代码来进行内联——它会(总是?)处理生成的字节(编译版本)——以及您在生成汇编代码(实际机器代码字节)时拥有的“工具”比您在 C#(或 IL)中拥有的工具更细粒度。

也就是说,您可以通过考虑 break 关键字以 C# 术语了解它的工作原理..

考虑这样一种可能性,即每个重要的内联函数都包含在 while (true) 循环(或 do while(false) 循环)中 - 并且每个源return 被翻译成 localVar = result; break; 语句集。然后你会得到这样的东西:

static Main() 
{
int number = 7;
bool a;
while (true)
{
if (number % 2 == 0)
{
a = true;
break;
}
a = false;
break;
}

Console.WriteLine(a); // Will always print the right thing! Yey!
}

类似地,在生成汇编时,您会看到生成了很多 jmp - 这些在道德上等同于 break 语句,但它们更加灵活(将它们视为匿名 goto或其他东西)。

因此您可以看到,抖动(以及任何编译为 native 的编译器)手头有很多工具可以用来做“正确的事情”。

关于c# - 具有绝对返回路径的方法如何内联?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9961867/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com