我正在使用以下代码对二叉树进行前序遍历:
public void PreorderTraversal(Action<BinaryTreeNode<T>> act) {
Action<BinaryTreeNode<T>> InnerTraverse = null;
InnerTraverse = (node) => {
if (node == null) return;
act(node);
InnerTraverse(node.Left);
InnerTraverse(node.Right);
};
InnerTraverse(this.Root);
}
这种使用本地定义的lambda在树上重现的方法是否更糟糕,从性能角度来看,简单地将InnerTraverse函数定义为BinaryTree类的一个方法,这是PreorderTraversal函数本身的定义?
答案 0 :(得分:1)
示例方法将由编译器翻译成如下:
class Closure
{
public Action<BinaryTreeNode<T>> act;
public Action<BinaryTreeNode<T>> InnerTraverse;
public void InnerTraverseFunc(BinaryTreeNode<T> node)
{
if (node == null) return;
this.act(node);
this.InnerTraverse(node.Left);
this.InnerTraverse(node.Right);
}
}
public void PreorderTraversal(Action<BinaryTreeNode<T>> act)
{
var c = new Closure();
c.act = act;
c.InnerTraverse = new Action<BinaryTreeNode<T>>(c.InnerTraverseFunc);
c.InnerTraverse(this.Root);
}
如您所见,每个T
的成本是一个新类型,每个根方法调用有2个堆分配,加上使用委托调用与使用常规静态递归方法的直接调用。
IMO额外的运行时成本并不是那么大,但同时由于在这种情况下使用递归lambda绝对没有好处,因此最好避免使用。