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

我主要使用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)循环中(或者执行while(false)循环) – 并且每个源返回都被转换为localVar = result;打破;一套陈述.然后你得到这样的东西:

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!
}

类似地,在生成程序集时,您将看到生成了大量的jmps – 这些是break语句的道德等价物,但它们更灵活(将它们视为匿名的getos或其他东西).

所以你可以看到,抖动(以及编译为本机的任何编译器)都有很多可以用来做“正确的事情”的工具.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


原文地址:http://msdn.microsoft.com/en-us/magazine/cc163791.aspx 原文发布日期: 9/19/2005 原文已经被 Microsoft 删除了,收集过程中发现很多文章图都不全,那是因为原文的图都不全,所以特收集完整全文。 目录 前言 CLR启动程序
前言 随着近些年微服务的流行,有越来越多的开发者和团队所采纳和使用,它的确提供了很多的优势也解决了很多的问题,但是我们也知道也并不是银弹,提供优势的同时它也给我们的开发人员和团队也带来了很多的挑战。 为了迎接或者采用这些新技术,开发团队需要更加注重一些流程或工具的使用,这样才能更好的适应这些新技术所
最近因为比较忙,好久没有写博客了,这篇主要给大家分享一下PLINQ中的分区。上一篇介绍了并行编程,这边详细介绍一下并行编程中的分区和自定义分区。 先做个假设,假设我们有一个200Mb的文本文件需要读取,怎么样才能做到最优的速度呢?对,很显然就是拆分,把文本文件拆分成很多个小文件,充分利用我们计算机中
在多核CPU在今天和不久的将来,计算机将拥有更多的内核,Microsoft为了利用这个硬件特性,于是在Visual Studio 2010 和 .NET Framework 4的发布及以上版本中,添加了并行编程这个新特性,我想它以后势必会改变我们的开发方式。 在以前或者说现在,我们在并行开发的时候可
c语言输入成绩怎么判断等级
字符型数据在内存中的存储形式是什么
c语言怎么求字符串的长度并输出
c语言函数的三种调用方式是什么
c语言中保留两位小数怎么表示
double的输入格式符是什么
长整型输出格式是什么
C语言中文件包含的命令关键字是什么
c程序如何编写x的y次方
c语言开根号代码是什么
c语言怎么进行字符串比较
c语言怎么进行强制类型转换
c语言运算符的优先级顺序是什么
c++用什么软件编程
中序遍历是怎么遍历的
h文件和c文件的关系是什么