1

我正在用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:感谢所有评论!我认为因为该事件被触发“相当多”,所以它可能在我的代码中是一种难闻的气味。虽然我没有考虑过缓存等。

4

5 回答 5

3

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

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

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

想一想(简化):

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

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

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

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

于 2013-11-04T18:52:27.707 回答
2

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

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

于 2013-11-04T18:52:38.677 回答
2

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

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

于 2013-11-04T18:52:59.070 回答
0

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

于 2013-11-04T19:05:19.047 回答
0

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

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

于 2013-11-04T18:54:14.717 回答