废除Globals?

时间:2008-09-16 00:13:59

标签: c# java oop global-variables

我有一组树对象,深度在20s左右。此树中的每个节点都需要访问其树的根。

一些解决方案:

  1. 每个节点都可以直接存储对根的引用(浪费内存)
    • 我可以通过“上升”(浪费周期)来计算运行时的根
    • 我可以使用静态字段(但这相当于全局变量)
  2. 有人可以提供不使用全局(在任何变体中)的设计,但分别在内存或周期中的#1或#2效率更高吗?

    编辑:由于我有一组树,我不能简单地将它存储在静态中,因为很难区分树。 (感谢maccullt)

6 个答案:

答案 0 :(得分:6)

将根作为参数传递给需要它的节点中的任何函数。

编辑:选项实际上如下:

  1. 将根引用存储在节点
  2. 不要存储根参考
  3. 将根参考存储在全局
  4. 将根引用存储在堆栈上(我的建议,访客模式或递归)
  5. 我认为这是所有可能性,没有选择5。

答案 1 :(得分:3)

为什么你需要取消全局变量?我理解全局变量的耻辱是坏事,但有时只是拥有包含所有元素的全局数据结构是最快的解决方案。

您需要权衡:代码清晰度和未来性能问题。这意味着'不要优化'。由于您处于优化阶段,因此有时需要削减一些可读性和良好的编程实践以支持性能。我的意思是,按位破解是不可读的,但它们很快。

我不确定你有多少树对象,但我个人选择了一个。除非你处理成千上万的树,否则指针实际上不会超过几个字符串。如果内存确实是一个非常重要的问题,请尝试两种方法(它们看起来相当简单)并通过分析器运行它。或者使用优秀的Process Explorer

编辑:我正在处理的其中一个应用程序有一个包含大约55K节点的节点树。我们构建树结构,但也维护一个用于O(1)查找的数组。比使用递归FindNodeByID方法时得到的O(m * n)要好得多。

答案 2 :(得分:2)

将根作为参数传递通常是最好的。如果你使用某种迭代器来导航树,另一种方法是在其中存储对root的引用。

答案 3 :(得分:1)

点#1是过早的内存优化。 #2是过早的性能优化。您是否已分析过您的应用以确定内存或CPU瓶颈是否会导致问题?如果没有,为什么牺牲一个更易于维护的设计来实现对您的用户没有帮助的“优化”?

我强烈建议你选择#2。每当你存储一些你可以改为计算的东西时,你正在做的就是缓存。有几次缓存是一个好主意,但这也是一个维护问题。 (例如,如果您通过更改其父节点将节点从一个树移动到另一个树但忘记还更新根字段,该怎么办?)如果您不需要,请不要缓存。

答案 4 :(得分:0)

您可以从TreeView派生一个类,然后添加一个单独的静态属性。这样你就可以有效地添加一个引用该类的单个实例的全局字段,但它的好处是它可以作为该类的命名空间。

答案 5 :(得分:0)

忽略内部类的厌恶,我可以定义一个Tree类并将节点定义为Inner类。每个节点都可以访问其树的状态,包括其根。

这可能最终与#1相同,具体取决于Java如何将节点与其父节点相关联。 (我不确定,我将不得不对其进行描述)