C# 要废除全球化吗?

C# 要废除全球化吗?,c#,java,oop,global-variables,C#,Java,Oop,Global Variables,我有一组树对象,深度在20秒左右。此树中的每个节点都需要访问其树的根 有两种解决方案: 每个节点可以直接存储对根的引用(浪费内存) 我可以在运行时通过“向上”(循环)计算根 我可以使用静态字段(但这相当于全局字段) 有人能提供一种不使用全局(在任何变体中)但在内存或周期中分别使用#1或#2更有效的设计吗 编辑:由于我有一组树,我不能简单地将其存储在静态中,因为很难区分树。(感谢maccullt)将根作为参数传递给节点中需要它的任何函数 编辑:选项实际上如下所示: 将根引用存储在节点中 根本不

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

有两种解决方案:

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


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

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

    编辑:选项实际上如下所示:

  • 将根引用存储在节点中
  • 根本不存储根引用
  • 将根引用存储在全局
  • 将根引用存储在堆栈上(我的建议,访问者模式或递归)

  • 我认为这是所有的可能性,没有选择5。

    为什么你需要取消全局?我理解globals是坏的和所有的污名,但有时仅仅拥有一个包含所有元素的全局数据结构是最快的解决方案

    您需要做一个权衡:代码清晰,未来的性能问题更少。这就是“还没有优化”的意思。由于您正处于优化阶段,有时有必要减少一些可读性和良好的编程实践,以提高性能。我的意思是,按位黑客虽然不可读,但速度很快

    我不确定你有多少树对象,但我个人会选择选项一。除非你处理的是成千上万的树,否则指针实际上不会超过几个字符串。如果内存确实是一个非常重要的问题,请尝试这两种方法(它们似乎很容易实现)并通过探查器运行它。或者使用优秀的

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

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


    我强烈建议你和#2一起去。每当您存储可以计算的内容时,您所做的就是缓存。有时缓存是一个好主意,但它也是一个维护难题。(例如,如果通过更改父节点将节点从一棵树移动到另一棵树,但忘记同时更新根字段,该怎么办?)。通过这种方式,您可以有效地添加一个全局字段,该字段引用类的单个实例,但它的好处是将名称空间范围限定到该类。

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


    这可能最终与#1相同,这取决于Java如何将节点与其父节点关联。(我不确定,我必须分析它)

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

    不清楚您是否有一个树林,在这种情况下,您需要几个根,还是只有一个根。在森林的情况下,我不知道静态如何解决你的问题,你不需要每棵树有一个根,并且每棵树都会引用它的根(解决方案1)。我没有想到这一点。在find中,当某些事情发生变化时,特别是当调用堆栈变得更深时,这往往会非常痛苦。我没有将其解释为递归。我可以有一段代码遍历树并在每个节点上执行。该代码将引用根.80k。。。??你担心不到十分之一的梅格。。。??听起来你是在为一个不存在的问题而紧张不是紧张,只是好奇。我认为这是一个很好的问题。当你认真考虑的时候,80K是微不足道的。当我最初看到这段代码时,我非常“wtf”,直到我通过一个分析器运行它,并意识到我们的字符串分配大约是它的400倍。我几乎可以肯定这将与#1相同,实际上没有其他方法可以实现它。