WEB开发网
开发学院软件开发C语言 Effective C# 原则31:选择小而简单的函数 阅读

Effective C# 原则31:选择小而简单的函数

 2009-02-19 08:16:07 来源:WEB开发网   
核心提示: // readonly name property:private string _name;public string Name{get{return _name;}}// access:string val = Obj.Name;相对函数的调用开销来说,属性访问器实体包含更少数的指令:

// readonly name property:
private string _name;
public string Name
{
 get
 {
  return _name;
 }
}
// access:
string val = Obj.Name;

相对函数的调用开销来说,属性访问器实体包含更少数的指令:对于函数调用,要先在寄存器中存储它的状态,然后从头到尾执行,接着存储返回结果。这还不谈如果有参数时,把参数压到堆栈上还要更多的工作。如果你这样写,这会产生更多的机器指令:

string val = Obj._name;

当然,你应该不会这样做,因为你已经明白最好不要创建公共数据成员(参见原则1)。JIT编译器明白你即须要效率也须要简洁,所以它会内联属性访问器。JIT会在以速度或者大小为目标(或者两个同时要求)时,内联一些方法,用函数体来取代函数的调用会让它更有利。一般情况不用为内联定义额外的规则,而且任何已经实现的内联在将来都可能被改变。另外,内联函数并不是你的职责。正好C#语言没有提供任何关键字让你暗示编译器说你想内联某个函数。实际上,C#编译器也不支持任何暗示来让JIT编译进行内联。你可以做的就是确保你的代码尽可能的清楚,尽可能让JIT编译器容易的做出最好的决定。我的推荐现在就很熟悉了:越小的方法越有可能成为内联对象。请记住:任何虚方法或者含有try/catch块的函数都不可能成为内联的。

内联修改了代码正要被JIT的原则。再来考虑这个访问名字属性的例子:

string val = "Default Name";
if ( Obj != null )
 val = Obj.Name;

JIT编译器内联了属性访问器,这必然会在相关的方法被调用时JIT代码。

你没有责任来为你的算法决定最好的机器级别上的表现。C#编译器以及JIT编译器一起为你完成了这些。C#编译器为每个方法生成IL代码,而JIT编译器则把这些IL代码在目标机器上翻译成机器指令。并不用太在意JIT编译器在各种情况下的确切原则;有这些时间可以开发出更好的算法。取而代之的,你应该考虑如何以一种好的方式表达你的算法,这样的方式可以让开发环境的工具以最好的方式工作。幸运的是,这些你所考虑的这些原则(译注:JIT工作原则)已经成为优秀的软件开发实践。再强调一次:使用小而简单的函数。

记住,你的C#代码经过了两步才编译成机器可执行的指令。C#编译器生成以程序集形式存在的IL代码。而JIT编译器则是在须要时,以每个函数为单元生成机器指令(当内联调用时,或者是一组方法)。小函数可以让它非常容易被JIT编译器分期处理。小函数更有可能成为内联候选对象。当然并不是足够小才行:简单的控制流程也是很重要的。函数内简单的控制分支可以让JIT以容易的寄存变量。这并不是只是写清晰代码的事情,也是告诉你如何创建在运行时更有效的代码。

上一页  1 2 3 

Tags:Effective 原则 选择

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接