关于何时使用临时对象来保存对对象的引用,而不是在每次使用时引用整个路径的经验法则? [关闭]

Posted

技术标签:

【中文标题】关于何时使用临时对象来保存对对象的引用,而不是在每次使用时引用整个路径的经验法则? [关闭]【英文标题】:Rule of thumb about when to use a temp object to hold reference to an object, rather than referering the whole path at every use? [closed] 【发布时间】:2018-05-27 11:59:36 【问题描述】:

我想这个问题在很大程度上取决于你喜欢什么以及非常有情境,但我今天刚刚遇到了一条通往gameobject 的路径,参考文献很长,我想如果是临时参考在这种情况下不会更好。

代码:

if (enlargeableButtons[i][j].gameObject.activeSelf && enlargeableButtons[i][j].IsHighlighted())

    enlargeableButtons[i][j].gameObject.SetIsHighlighted(true, HoverEffect.EnlargeImage);

如果路径这么长,需要检查多个数组索引,肯定会更快,但由于额外的对象,这样做也更昂贵:

GameObject temp = enlargeableButtons[i][j].gameObject;

if (temp.activeSelf && temp.IsHighlighted())

    temp.SetIsHighlighted(true, HoverEffect.EnlargeImage);

但是要花多少钱,值得吗?

【问题讨论】:

这看起来像是过早优化的主要示例。 它不是一个临时对象,它是一个临时变量。 C# 中的变量包含结构(值类型)或引用(或者,更罕见的是,指针)。单个对象可以有多个引用,而引用本身非常小。 这看起来像是编译时优化的候选者。当有数组引用时,任何人都可以验证 C# 是否会处理这个问题? 这只是为了减少代码行长的可读性。而已。除非您调用用于搜索游戏对象的 Unity API,例如 GameObject.Find(),否则您不会注意到任何性能提升。 【参考方案1】:

我非常怀疑您是否会看到使用直接引用而不是通过锯齿状数组来获得任何性能提升。 也许如果这段代码在一个非常紧凑的循环中运行并且有很多很多的迭代,你可能会得到几毫秒的差异。

但是,从可读性的角度来看,第二个选项更具可读性 - 所以我肯定会选择它。

作为一项规则 - 您应该为清晰而设计代码,而不是为了性能。 编写代码,以尽可能最清晰的方式传达它正在实现的算法。 设定性能目标并根据它们衡量代码的性能。 如果您的代码无法达到您的性能目标,请找出瓶颈并加以处理。 设计代码时,不要将时间浪费在纳米优化上。

还有一个个人故事来说明我的意思: 我曾经写过一个项目,我有很多obj.child.grandchild 电话。在开始编写项目后,我意识到这将是很多调用,我刚刚在我正在处理的类上创建了一个属性,引用了那个孙子,我的代码突然变得更好了。

【讨论】:

【参考方案2】:

声明GameObject temp 只会创建对enlargeableButtons[i][j].gameObject 的引用。这是额外的开销,但不多。除非您重复数千次或更多次,否则您不会注意到差异。

作为个人规则,如果我只需要引用一次,我不会为它声明一个变量。但是如果我需要多次使用enlargeableButtons[i][j].gameObject 之类的东西,那么我声明一个变量。

【讨论】:

我更新了我的措辞以澄清。 拥有一个额外的局部变量的代价仅仅是堆栈帧在设置帧时增加了一个额外的字。这实际上根本没有任何成本,除非它导致堆栈溢出异常,这实际上并不是真正的问题。

以上是关于关于何时使用临时对象来保存对对象的引用,而不是在每次使用时引用整个路径的经验法则? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

何时需要获取PermanentIDsForObjects:error:?来自2个不同的班级?

关于何时在 TypeScript 中调用装饰器的困惑

返回对临时对象成员的 const 引用

如果没有保存引用,SystemTimers.Timer 何时被视为垃圾?

为啥非常量引用不能绑定到临时对象?

cpp►动态内存分配与析构之复制构造函数/赋值运算符