4

这是源代码:

public int indexOf(Object o) {
    if (o == null) {
        for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
        }
    }
    return -1;
}

为什么没有这个:只有一个循环和 if 语句。

public int indexOf(Object o) {

   for (int i = 0; i < size; i++){
       if (o == null) {
             if (elementData[i]==null)
                return i;
        else {
             if (o.equals(elementData[i]))
                return i;
        }
    }

    return -1;
}

第一个片段必须有两个循环,但有人说上面的代码性能很好。为什么?

4

4 回答 4

4

实际上,两个片段都做同样的事情。但是,第二个片段的性能可能会更差,因为比较语句会被多次评估,而不是第一个片段中只有一个比较。每个代码片段经历的循环迭代次数相同,但所需的比较次数不同。就那么简单。

于 2012-09-01T01:26:17.303 回答
0

想法是第一个只需要比较o一次null,而第二个必须在循环中的每次通过时进行比较。

于 2012-09-01T01:26:19.240 回答
0

使用单个循环,您必须在每次迭代时重新检查条件 - 因此需要更多工作。

对于第一个示例,您只需检查一次条件。

如果在没有优化的情况下编译(以字面方式),那么第二个示例会更慢。

但是,大多数编译器确实有技巧,可以将第二个示例中的代码转换为与第一个示例等效的机器代码。但是,这在很大程度上取决于编译器优化标志(即优化的内容 - 运行时间或代码大小)

于 2012-09-01T01:26:49.533 回答
0

第二种形式检查是否o == nullsize - 1次数更少。

假设无论如何都没有为您完成这样的优化。如果不尝试,这不会是假设。

有时在循环中的最终机器代码中使用较少的指令也有好处,尽管它不太可能产生任何影响。

减少可能分支的数量也可以提高性能,因为预取错误指令的可能性较小。(感谢安德烈亚斯亨宁)。

总而言之,当您需要优化某些东西时,将事物移出循环的想法是一件足够合理的事情,但在这种情况下可能并不重要。

刚看到你的评论。考虑到有多少代码进入 ArrayList.indexOf,这是一个合理的地方来做你能想到的每一个小小的挤压。

于 2012-09-01T01:30:58.830 回答