我知道这已被问过很多,但仅限于C / C ++和Java。 问题与使用常量表达式的性能优势有关:
当我调用只有常量作为参数的静态函数时,有没有办法告诉编译器它应该在编译时评估调用并用结果替换调用?
示例:
const double pi = Math.PI; //works as Math.PI is a constant
const double spi = Math.Sin(Math.PI); //compiler error, because expression must be constant
是否没有指令(更好:属性)明确地告诉编译器像Math.Sin()这样的静态方法没有在内部修改或读取任何数据,因此技术上可以在编译时评估调用?
哦,请不要回答#34;只做const double spi = 0
" :),因为我的例子只是我所遇到的问题的简化版本:在保持最高性能的同时提高代码可维护性。
感谢您的帮助 - 非常感谢!
答案 0 :(得分:4)
对于数值常数,我看到两个选项:
选项一:使用静态只读(在启动时计算一次):
class MyCalc
{
private static readonly double spi = Math.Sin(Math.PI);
private static readonly double pi = Math.Sin(Math.PI);
public void Execute()
{
// .. whatever
}
}
选项二:使用袖珍计算器执行计算并对这些常量进行硬编码:
class MyCalc
{
// Math.Sin(Math.Pi)
private const double spi = 0;
// Math.Pi
private const double pi = 3.141592653589793;
public void Execute()
{
// .. whatever
}
}
我不确定,如果编译器可以在计算中完全优化选项1,但它应该是最易读和可维护的方式。
如果您希望尽可能多地在编译时进行操作,事情会变得更加困难。在C ++下你有模板。我觉得写起来很麻烦,但人们会amazing things完成它。使用compile time functions似乎更容易,但我还没有尝试过。 D有CTFE这真的很强大。但D是一个利基,我会避免写任何严重的代码。我不知道其他语言有相当明确的预编译评估,但我确信有一些。
编译器现在已经退出智能。很可能编译器可能会在没有提示的情况下内联优化函数调用。使用DotNet 4.5,我们得到了AggressiveInlining - 属性,因此我们可以强制编译器进入正确的方向。 C / C ++有类似的东西,有problems。我的一般建议是避免inline
直到你确切知道自己在做什么。
如果你真的不想从C#走这条路,那么我眼中最好的选择是使用上面提到的功能用C ++编写你的功能,编写一个易于使用的C接口并通过{{3 }}。但如果真的值得,请自己帮个忙。永远不要忘记两个优化规则:
答案 1 :(得分:2)