函数调用有一定的代价:参数需要保存到堆栈上或寄存中(在可能的情况下JIT使用ecx和edx来传递前俩个参数),执行函数的prolog和epilog也需要一定的时间。Inlining可以避免函数调用的代价,然而CLR的JIT inliner较为保守。下面是一些最重要的规则:
l IL代码大于32字节的函数不被inline。
l 虚拟函数(virtual method)调用或接口函数(interface method)调用不被inline
l 使用复杂的程序流控制的函数不被inline。复杂的程序流控制指if/then/else之外的流控制语句。
l 包含异常处理快的方法和产生异常的方法不被inline。可以将throw语句移到一个独立的函数中来避免这个问题。下面是一个例子:
public T this[int index] {
get {
// Fllowing trick can reduce the range check by one
if ((uint) index >= (uint)_size) { ThrowHelper.ThrowIndexOutOfRangeException();}
return _items[index];
}
}
l 包含值类型参数的方法不被inline。
注意不要为了inline一个方法而牺牲程序的正确性。同时要注意inline较大的函数可能导致工作集的增长。
如果你读过如下的文章:
你会注意到我基本上是翻译了该文章的一部分。不过注意有分歧的地方可以假设我的信息更准确。:)
打印 | 张贴于 2004-07-17 09:51:00 | Tag:Performance
留言反馈