XobotOS:为什么C#二叉树基准测试使用结构?

时间:2012-05-17 05:41:00

标签: c# mono benchmarking xobotos

对xobotos中的reputed performance gains感到好奇,我检查了二叉树benchmark code

binary tree node的Java版本是:

private static class TreeNode
{
    private TreeNode left, right;
    private int item;
}

C# version是:

struct TreeNode
{
  class Next
  {
    public TreeNode left, right;
  }

  private Next next;
  private int item;
}

我想知道在这里使用struct的好处是什么,因为Next和Previous指针仍然封装在一个类中。

嗯,有一个叶子节点是纯值类型,因为它们不需要左右指针。在典型的二叉树中,一半节点是叶子,这意味着对象数量减少了50%。不过,所列出的业绩增长似乎要大得多。

问题:还有更多吗?

此外,由于我不会想到在C#中以这种方式定义树节点(感谢Xamarin!),其他数据结构可以从非显而易见的方式使用结构中获益吗? (尽管这有点偏离主题并且开放性。)

4 个答案:

答案 0 :(得分:1)

我只是遇到了这个奇怪的代码而且遇到了同样的问题。如果您更改代码以匹配Java版本,它将运行稍慢。我相信大多数'struct TreeNode'都会被装箱并分配,除了底行。但是,每个节点都会产生2个分配:盒装TreeNode和类Next。分配节省很快就会消失。 IMO,这不适合使用struct。

答案 1 :(得分:0)

结构可以在堆栈而不是堆上分配(但不是在所有情况下),这意味着它们一旦超出范围就会被解除分配 - 垃圾收集器不会参与该场景。这可以导致更小的内存压力和更少的垃圾收集。此外,堆栈(主要)是内存的连续区域,因此访问它具有更好的位置,这可以(再次,可能)提高CPU级别的缓存命中率。

Microsoft choosing between classes and structures指南:

  • 结构应该很小(一般是16个字节)和短暂的
  • 他们应该是不可改变的

如果满足这些要求,那么在类上使用结构将导致性能提升。

答案 2 :(得分:0)

这将两个节点分组为一个分配,理想情况下将总分配数减半。

IMO这使得比较毫无意义。

答案 3 :(得分:-1)

我不认为在这里使用struct会产生任何不同。特别是在查看TreeNode的源代码之后,TreeNode的实例总是在构造函数和递归的bottomUpTree调用中复制。