gpt4 book ai didi

C#:为什么类变量调用实现的接口(interface)方法比接口(interface)变量更快?

转载 作者:可可西里 更新时间:2023-11-01 07:45:17 24 4
gpt4 key购买 nike

我在 .NET 中发现了这种奇怪的行为,甚至在查看了 CLR via C# 之后也是如此我还是很困惑。假设我们有一个带有一个方法的接口(interface)和一个实现它的类:

interface IFoo
{
void Do();
}

class TheFoo : IFoo
{
public void Do()
{
//do nothing
}
}

然后我们只想实例化这个类并以两种方式多次调用这个 Do() 方法:使用具体类变量和使用接口(interface)变量:

TheFoo foo1 = new TheFoo();

Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (long i = 0; i < 1000000000; i++)
foo1.Do();
stopwatch.Stop();
Console.Out.WriteLine("Elapsed time: " + stopwatch.ElapsedMilliseconds);

IFoo foo2 = foo1;

stopwatch = new Stopwatch();
stopwatch.Start();
for (long i = 0; i < 1000000000; i++)
foo2.Do();
stopwatch.Stop();
Console.Out.WriteLine("Elapsed time: " + stopwatch.ElapsedMilliseconds);

令人惊讶的是(至少对我而言)耗时相差大约 10%:

Elapsed time: 6005
Elapsed time: 6667

差别不大,所以在大多数情况下我不会太担心这一点。但是,即使查看了 IL 代码,我还是无法弄清楚为什么会发生这种情况,所以如果有人指出我明显缺少的东西,我将不胜感激。

最佳答案

您必须查看机器代码才能了解发生了什么。当您这样做时,您会看到抖动优化器已完全删除了对 foo1.Do() 的调用。像这样的小方法会被优化器内联。由于方法体不包含任何代码,因此根本不会生成任何机器代码。它不能对接口(interface)调用进行相同的优化,它不够聪明,无法逆向工程接口(interface)方法指针实际上指向一个空方法。

检查 this answer有关抖动执行的常见优化列表。请注意该答案中提到的有关分析的警告。

注意:查看发布版本中的机器代码需要更改一个选项。默认情况下,即使在发布版本中,调试代码时优化器也会被禁用。工具 + 选项、调试、常规,取消勾选“在模块加载时抑制 JIT 优化”。

关于C#:为什么类变量调用实现的接口(interface)方法比接口(interface)变量更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6396362/

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