【问题标题】:Enhanced for-loop vs handling objects manually增强的 for 循环与手动处理对象
【发布时间】:2014-05-09 02:26:06
【问题描述】:

在某些情况下,为了方便我们使用循环,但也可以“手动”执行一些操作,例如从我的应用处理 MenuItems:

  1. 我创建了一个MenuItems 的小数组,然后使用增强的for 循环遍历它。

    MenuItem[] fileActionsToLock ={ mMenu.findItem(R.id.action_share),
                                    mMenu.findItem(R.id.action_rename),
                                    mMenu.findItem(R.id.action_copy),
                                    mMenu.findItem(R.id.action_move) };
    for (MenuItem i : fileActionsToLock) {
        i.setEnabled(false);
        i.getIcon().setAlpha(100);
    }
    
  2. 我将这些值分别应用于每个 MenuItem

    mMenu.findItem(R.id.action_share).setEnabled(false);
    mMenu.findItem(R.id.action_share).getIcon().setAlpha(100);
    mMenu.findItem(R.id.action_rename).setEnabled(false);
    mMenu.findItem(R.id.action_rename).getIcon().setAlpha(100);
    mMenu.findItem(R.id.action_copy).setEnabled(false);
    mMenu.findItem(R.id.action_copy).getIcon().setAlpha(100);
    mMenu.findItem(R.id.action_move).setEnabled(false);
    mMenu.findItem(R.id.action_move).getIcon().setAlpha(100);
    

由于元素很少,所以在视觉上表现是一样的。

  • 但是哪个代码运行得更快,为什么?
  • 另外,fileActionsToLock 数组和临时MenuItem i 将在哪个时间点被垃圾回收?

【问题讨论】:

    标签: java android performance foreach


    【解决方案1】:

    非循环方法肯定更快。比较标准的for 循环更容易,因为我们确切地知道发生了什么,因此我将使用它作为示例。当循环开始时,我们声明变量检查是否满足条件,然后运行第一个代码块。在运行第一块代码之后,我们在检查条件之前运行一条语句,然后重复。

    所有这些额外内容(声明一个额外变量、检查条件和运行最终语句)都不会在您的第二个示例中发生。发生的事情越来越少,所以它总是会更快。也就是说,对于现代计算机来说,这些额外的操作花费的时间或精力非常少,因此真的不值得担心。差异可以忽略不计。如此之小,以至于它们不太可能对您的应用程序产生任何影响。即使foreach 循环比for 循环更快,仍然执行的操作不会出现在您的手动示例中。

    在决定何时使用其中一种时,您应该使用的标准是可读性、功能性、可扩展性等。循环更容易阅读,并且需要的代码行数更少。该循环可用于动态检查条件,因此它更具功能性。最后,循环更具可扩展性。您可以稍后将更多Objects 添加到循环数组中,而无需更改代码。

    至于垃圾回收,应该没有什么区别。当任何可访问和运行的代码中不存在对它们的引用时,它们都有资格被收集。

    【讨论】:

      【解决方案2】:

      (1) 我认为任何一个都不会比另一个运行得明显快。循环将有更多开销(例如,请参阅下面的 cmets 关于需要迭代器)但应该花费大约相同的时间来完成,就像您只是单独写出所有步骤一样。底线 - 你不会注意到差异。我会使用循环,因为它可能使您的代码更易于阅读。

      (2) 什么时候被垃圾回收很难说。通常,当没有更多指向它的引用时,一个对象将有资格进行垃圾回收。实际发生的方式和时间取决于您的其余代码和垃圾收集您的单个设备的 JVM 正在运行。不同版本的 android 操作系统有不同种类的垃圾收集器。 Some more about garbage collectors 可以在这里找到,also here

      【讨论】:

      • 手动的会稍微快一点,因为它不需要像增强的 for 循环那样创建迭代器。但这并没有什么区别——尤其是在这种情况下,项目很少。不过,在使用 for 循环时 +1。显着更容易并且扩展性更好。
      • 循环展开是一种常见的优化,比将语句组合成一个循环更容易。将其编写为循环不仅更清晰,而且将展开决策留给了 JVM,它拥有更多关于运行时环境的数据。
      • 具有 JIT 的 JVM 不会自行展开循环吗?迭代器在创建时会产生更多开销并降低整个过程的速度,但我不知道实际代码会在循环外执行得更快。
      【解决方案3】:

      您可以阅读它in this article。手动方式通常比增强的 for 循环更快,因为它不调用迭代器上的任何方法。它也比普通的 for 循环更快,因为它不包含跳转和递增指令 - 但这并不是真正的问题,因为没有人会手动操作数百个元素以从 CPU 获得几毫秒的时间。

      【讨论】:

        猜你喜欢
        • 2012-03-20
        • 2014-02-08
        • 1970-01-01
        • 2020-02-06
        • 2014-02-23
        • 2011-01-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多