【问题标题】:Does setting a object to null multiple times have a performance impact?多次将对象设置为 null 是否会对性能产生影响?
【发布时间】:2013-11-15 11:46:20
【问题描述】:

我正在用 java 制作一个在鼠标后面使用“尾巴”的游戏。我使用 MouseMotionListener 并使用 mouseDragged(MouseEvent e) 函数将鼠标的位置添加到数组中。

所以只要触发了 mouseDragged(MouseEvent e) 函数,它就应该将当前鼠标位置添加到一个数组中,当拖动停止时,该数组应该被清除。

我的想法是使用 mouseMoved(MouseEvent e) 函数将数组设置为空。我可以这样做:

public void mouseMoved(MouseEvent e) {
    if(myTailArray != null) {
        myTailArray = null;
    }
}

或者像这样:

public void mouseMoved(MouseEvent e) {
    myTailArray = null;
}

最后一个方法意味着 myTailArray 将被设置为 null 很多次都没有。但这对性能有影响吗?

编辑:为了清楚起见,我知道当鼠标在拖动后没有移动时,这可能会导致错误。我使用 MouseListener 来重置鼠标的按下和释放,但我只是好奇。

EDIT2:感谢所有 cmets!我认为因为该事件被触发“相当多”,所以它可能在我的代码中是一种难闻的气味。虽然我还没有考虑缓存等。

【问题讨论】:

  • 不检查就做。
  • 回答任何性能问题的最佳方式始终是测试。您可以编写一两个示例应用程序来测试不同的选项并亲自查看。
  • 您补充说您“没有考虑过缓存等”。小心,你仍然可能错过了重点。您没有考虑“缓存等”。而你不应该。不在鼠标事件处理程序中。您没有想到的真实是实际的性能要求、分析和适当的优化。
  • @JasonC 你是绝对正确的。问题是我喜欢优化东西,但我没有太多经验。我并不是真的担心它会对我的程序产生太大影响,只是担心它会产生什么样的影响。
  • 如果你喜欢优化东西,你应该尝试优化影响更大的东西。这篇文章虽然过时了,但可能会占用你一点时间onjava.com/pub/a/onjava/2002/03/20/optimization.html

标签: java


【解决方案1】:

显然不是,因为您在无法注意到程序实际性能的差异后不得不来这里询问。 :)

关键是,除非它不满足您的性能要求,否则不值得优化。

在任何情况下,执行额外分配与分支的性能差异与例如相比完全可以忽略不计。生成和处理鼠标移动事件所花费的时间。

想一想(简化):

  1. 用户决定移动鼠标。
  2. 用户的大脑通过钠/钾反应链向手臂和手部的肌肉发送电脉冲。
  3. 肌肉运动产生的力量克服了鼠标在桌子上的摩擦,鼠标移动。
  4. 光学鼠标对桌面上的图像进行采样,在硬件中比较连续图像并计算偏移量。
  5. 运动数据序列化并通过 USB 发送,发生各种同步。
  6. 生成和处理硬件中断、读取传入数据、缓冲、分派给适当的驱动程序。
  7. 鼠标位置已更新。通过对显存中的数据块进行块传输和修改来重绘光标。
  8. 窗口系统检查其窗口、检查鼠标状态并将事件分派到同步的线程队列。
  9. Swing 窗口接收原生事件,检查自身内部状态,转换为 Swing 事件并通过对象树分发消息,最终导致...
  10. 正在调用您的鼠标移动处理程序。

那么,您为什么担心分配或分支中的几纳秒差异?只是方法调用本身中的堆栈清理代码将使您的分配相形见绌。

编辑:顺便说一下,这里有一篇关于微调的文章有些过时但仍然有效:http://www.onjava.com/pub/a/onjava/2002/03/20/optimization.html

其中一个关键点是“在开始调整之前始终设定目标,以便您知道何时停止。”这篇文章不仅有一个很好的案例研究可供您使用,它还以一个很好的一般过程大纲结束:识别瓶颈、设置目标、测试、配置文件并进行相应的优化。

【讨论】:

    【解决方案2】:

    设置一个非易失性实例变量所花费的时间可以忽略不计:它只是一个本地 CPU 缓存写入操作,没有任何昂贵的内存屏障指令。根据具体情况,JIT 编译器可能会完全消除某些写入。

    但是为了把这些事情放在眼里,我应该补充一点,我们正在讨论 0.5 ns 与可能 10 ns 的最坏情况,完整的volatile 写入。仅调用该方法可能比写入本身花费更多时间。鼠标每秒最多生成 100 个报告,即在挂钟时间的每一秒内花费 100 x 10ns = 1 µs 的时间(最坏的情况!)。

    【讨论】:

      【解决方案3】:

      这种事情是你不应该关心的微优化。如果有差异,即使该方法被调用数千次,也可以忽略不计。它甚至可能不是您期望的差异:根据值是 null 或非 null 的频率,添加的分支指令可能会超过冗余分配(分支在许多架构上相对昂贵)。

      通常,在没有证明实际性能问题的情况下尝试优化这类事情会适得其反。

      【讨论】:

        【解决方案4】:

        如果它有任何影响,你无论如何都不会注意到它。

        但是没有 if 语句的版本应该“更快”,因为比较比赋值更昂贵。 (我记得从 uni 虽然找不到任何参考来证明它)

        【讨论】:

        • 我认为这不是一个好主意,这样会使程序变慢一点的一切都不值得优化。在我看来这有点愚蠢。我不知道分配比比较更昂贵,谢谢!
        • 实际上,大多数使程序慢一点的东西实际上并不值得优化。优化已经远远超过性能要求的代码,并专注于实际瓶颈的一小部分,两者都会适得其反。您的用户将花费更多的时间等待您完成并测试您的软件,而他们会因为鼠标移动而额外等待 10 纳秒而损失惨重。
        【解决方案5】:

        第二种(通常是首选)方法会更慢的唯一情况是在密集多线程环境中,其中冗余设置为 null 会导致页面更改并导致缓存抖动。它会发生,但如果您处于这种情况下,您很可能已经意识到潜在的问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-11-27
          • 2012-02-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多