繁体   English   中英

如何验证函数是否已在C#中缓存?

[英]How can I verify if a function has been cached in C#?

我在C#中创建了以下函数:

float GetPI()
{
  return 22.0f/7.0f;
}

void Calculate()
{
  float f1 = GetPI()*4;
  float f2 = GetPI()*5;
}

如果创建发行版本,我如何能够验证JIT编译器是否将缓存22/7计算,或者是否将在每次调用GetPI函数时进行计算?

PS:我没有可视的C#studio专业版

编辑:将22/7更改为22.0f / 7.0f,以使示例函数更准确

我不确定被缓存是什么意思。 除非编译器不进行任何常量折叠(在这种情况下会折叠)或运行时不内联函数(在这种情况下可能会内联),否则编译器不会为您自动进行任何“缓存”。


表达式22f/7f是一个常量表达式,可以在编译时进行评估(也称为常量折叠 )。 因此,在已编译的程序集中,它将显示为:

float GetPI()
{
  return 3.142857f; // however many digits of precision
}

如果有机会,编译器将始终进行这种优化。 除非有一个禁用该选项的编译器选项(我不确定是否存在)。 为了验证这种情况是否发生,您可以使用Reflector(正如其他人所指出的)来查看编译后的程序集。 您应该看到,无论是Debug版本还是Release版本,还是使用Express版本,它的确可以做到这一点(除非明确禁用此优化)。


如果函数足够简单,则运行时可能会内联函数调用。 因此,与其调用此函数,不如将其插入到函数调用中。 鉴于这只是一个返回一些数字的函数,因此可能会进行此优化。 我不知道是否有一种方法可以在没有通过调试器实际看到JIT编译代码的情况下查看是否发生了这种情况。


如果您要像备忘录中那样缓存,那么不会自动进行,您必须自己做。


如果要绝对保证编译器将“缓存”该值(如不重新计算商),则应将值声明为常量(或使用现有的更准确的System.Math.PI常量)。 在运行时什么都没有确定,在编译时一切都是已知的。 每次你使用这个值的时候,这是“内联”,所以你不必担心。

const float PI = 22f / 7f; // will be stored as 3.142857f

// or another way, if you need PI to be a float but want a more accurate value
const float PI = (float)Math.PI; // will store as much precision possible
// note that this only works because Math.PI is declared as a constant

下载并安装.NET Reflector(最初由Lutz Roeder编写,现在由Red Gate维护)。 如果您不想付款,则可能需要寻找较旧的版本。

在Reflector中打开代码时,可以看到编译器进行了哪些更改。

这不会向您显示JIT优化,您需要为此在调试器中逐步通过机器代码,但是我很确定这种情况将由C#编译器评估。

有很多方法。 一种方便的方法是使用.NET Reflector。

在Reflector中打开程序集,选择C#,在树视图中找到方法,然后选择“工具/反汇编”。 反汇编程序将显示以下内容:

public float GetPI()
{
    return 3f;
} 

暂无
暂无

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

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