gpt4 book ai didi

c# - C# JITter 能否优化重复的委托(delegate)调用?

转载 作者:太空宇宙 更新时间:2023-11-03 18:55:20 24 4
gpt4 key购买 nike

在我当前的代码库中,复杂的 if 语句通常被委托(delegate)调用所取代。由于代码的结构,在应用程序的过程中将多次调用同一个委托(delegate)。例如,

class ExampleClass
{
private delegate double ExampleDelegate(double x, double y);
private ExampleDelegate _exampleMethod;
private bool _condition1;

...

public double ApiFunction(List<double> a, List<double> b, bool condition2)
{
if ((_condition1 && !condition2) || getCondition3())
{
_exampleMethod = adder;
}
else
{
_exampleMethod = subtracter;
}

double finalResult = 0;

for (int i = 0; i < a.Count; i++)
{
finalResult += _exampleMethod(a[i], b[i]);
}

return finalResult;
}

private double adder(double a, double b)
{
return a + b;
}

private double subtracter(double a, double b)
{
return a - b;
}
}

由于这里的性能是一个问题,我想知道 JITter 是否最终会意识到每次都会调用其中一个方法并内联或以其他方式优化调用。

那么,C# JITter 能否内联或以其他方式优化重复的委托(delegate)调用

最佳答案

事实并非如此。委托(delegate)调用始终是间接调用,并在运行时动态绑定(bind)。这发生在调用时,只有那时委托(delegate)对象的值才是已知的。抖动在此之前运行,优化器无法改进它们,它不知道究竟要调用什么。

请注意它无法知道目标方法是实例方法还是静态方法,它假定是实例方法。如果重新调整调用堆栈是静态的,则调用 stub 需要完成额外的工作。对于 x64 代码来说,额外的工作量更大。代码片段中值得注意的是,静态方法通常更有意义,因此请注意这一点。

第一次调用是昂贵的,那是在创建调用 stub 并且需要调整目标方法时。因为在这种情况下,抖动已经正确地猜测了方法的样子, stub 只是一个简单的 JMP 指令。此后的任何调用都以正常速度运行,并且在 JMP 之外,不会比正常调用慢很多,尽管您无法像这些小方法通常那样从内联中获益。没有进行任何更改,.NET 没有任何类似热点编译器的东西,因为它不使用解释器。

您必须进行测量,请注意这是非常快的代码,因此简单的基准测试错误往往会造成伤害并且测量不会非常一致。但是只有当你发现你有一个实际的性能问题时才考虑花时间在它上面。这并不常见,委托(delegate)们不烂。

关于c# - C# JITter 能否优化重复的委托(delegate)调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46853658/

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