繁体   English   中英

呼叫方法会降低性能吗?

[英]Does call method slow down performance?

例如 :
代码1:

void Main()
{
    Console.WriteLine("Some texts");
}

代码2:

void Main()
{
    Foo();
}

void Foo()
{
    Console.WriteLine("Some texts");
}

代码2运行速度比代码1慢吗? 我虽然在构建版本时,JIT将内联代码2,然后代码2将以代码1的速度运行。但是当我使用LinqPad测试它时,我得到了IL结果:

代码1:

IL_0000:  ldstr       "Some texts"
IL_0005:  call        System.Console.WriteLine

代码2:

IL_0000:  ldarg.0     
IL_0001:  call        UserQuery.Foo

Foo:
IL_0000:  ldstr       "Some texts"
IL_0005:  call        System.Console.WriteLine
IL_000A:  ret      

我们可以看到代码2中的IL结果有一些额外的步骤来调用Foo(),这是否证明代码2比代码1运行得慢?

首先,您正在查看IL,而不是JITted汇编代码。 你所展示的并不能证明什么。 您需要查看JITted输出以查看JITter是否内联了代码。 请注意,JITter从平台到平台(例如x86与x64)以及Framework的版本与Framework版本不同。

其次,当然,由于书面版本2的运行速度比版本1慢。 当我说“as written”时,我的意思是假设JITter没有在第二版中内联调用。 额外的调用添加了一些机器指令,当然需要几个额外的周期来执行(再次,不要忘记我说“写的!”)。 然而,性能上的差异非常极大,不太可能有意义。 您必须在最紧密的循环中进行数万亿次和数万亿次迭代才能看到有意义的性能差异。

如果没有c#-compiler或jit-compiler内联,则方法调用会使代码执行变慢一点。 但是,除非您的代码在循环中运行并且执行了一百万次左右,否则您应该专注于生成干净,易懂和可维护的代码。 当我开始编写单个语句的执行时间时,以毫秒或微秒为单位进行测量。 今天它们以纳秒为单位。 时间通常主要浪费在I / O操作上。 糟糕的算法也可能被指责一些。 如果您的设计结构清晰,那么与从一开始就经过时间优化的代码相比,将性能较差的代码部分替换为更好的代码部分会更容易,因此可能结构很糟糕。

我最近经历过这个。 我不得不在ac#program中用Visio生成一个复杂的图形。 原来,Visio自动化非常缓慢。 创建图形需要几分钟。 幸运的是,我已将所有图形内容放在一个组件中,该组件通过产品中性界面显示图形命令。 即:界面不包含任何Visio特定的东西。 用一个新的SVG组件替换我的Visio组件非常容易,它在不到一秒的时间内完成了相同的任务。 此外,绝对不能在我的算法或程序的任何其他部分进行任何更改。

原因是,我的图形包装器组件添加了更多的方法调用。 此外,它可以通过界面访问,这会使整个事情变得更加缓慢。 但是,最后,正是这个接口和这些额外的方法调用,使我能够实现更快的解决方案。 记住:分钟与不到一秒钟!

在这种情况下,通过实现,因为这是我最后一次阅读这些内容,是的,它将被内联。

一般来说,答案可能是 - 关于内联规则的内容是哪些文档是信息材料,主要是在博客中,而不是规范性文档。 不仅版本之间的细节会发生变化,他们几乎肯定会。

在实践中:

如果您怀疑性能热点可以从手动内联中受益,那么请尝试并再次进行配置。 或者至少查看该特定部分的jitted代码。

理论上:

尽管如此,我还是喜欢知道内联的小方法,都是一样的。

它如此微不足道(读:可能有),你不应该担心它。

C#编译器不进行内联,这是您在IL代码中看到的内容。 内联是JIT优化器的工作,它在运行时执行它(如果它决定内联函数使程序更有效)。

编译器创建自己对代码(汇编代码)的解释,因此代码示例将在CPU中以相同的方式处理。 (在发布模式下)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM