gpt4 book ai didi

java - 在开始迭代之前检查 Java 集合是否为空有用吗?

转载 作者:搜寻专家 更新时间:2023-11-01 03:51:33 24 4
gpt4 key购买 nike

在下面的两种样式中,分配了一个Iterator对象。在迭代之前检查集合是否为空有用吗?我不知道这是否属于“过早优化”。希望对 JVM 垃圾收集器有深入了解的人可以提供见解。

此外,我不知道 Java 编译器如何处理 for-each 循环。我假设样式 B 自动转换为样式 A。但是......也许包含一张空头支票。

循环样式 A

Collection<String> collection = ...
Iterator<String> iter = collection.iterator();
while (iter.hasNext()) {
String value = iter.next();
// do stuff
// maybe call iter.remove()
}

循环样式 B

Collection<String> collection = ...
for (String value : collection) {
// do stuff
}

循环样式 A(已修改)

Collection<String> collection = ...
if (!collection.isEmpty()) {
Iterator<String> iter = collection.iterator();
while (iter.hasNext()) {
String value = iter.next();
// do stuff
// maybe call iter.remove()
}
}

循环样式 B(已修改)

Collection<String> collection = ...
if (!collection.isEmpty()) {
for (String value : collection) {
// do stuff
}
}

最佳答案

是的,这绝对是一个过早的优化,如果它能有所帮助的话。您的循环必须对性能非常关键,并且通常使用空集合调用,并且由于某些原因无法优化创建实际迭代器对象的大部分成本。

在那场完美 Storm 中,这种巨大的源丑陋可能是合理的。但更有可能的是,您可以重新安排一些内容以帮助编译器更好地优化,例如将迭代器保留在本地。


迭代器对象(通常?)是函数局部的,因此创建起来很便宜(可以只存在于寄存器中,不需要堆分配)。参见https://www.beyondjava.net/escape-analysis-java有关 JVM 如何在对象上执行“标量替换”的一些详细信息,如果逃逸分析证明它是纯本地的,则其他代码看不到对它的引用。因此,可能的节省甚至不包括内存分配。

如果这在执行某些操作之前确实进行了 JIT 编译以进行单独检查,那么即使集合不为空,它也会始终运行额外的指令。

针对最常见的情况进行优化。与其添加额外的代码来略微加快罕见的空情况,不如将其保留以加快常见的非空情况。

我认为大多数循环倾向于在非空集合上运行。小在某些情况下很常见,但空的通常很少见。也许您有一个经常或通常在空集合上运行的循环,例如程序中很少使用的功能。那么值得考虑针对这种情况进行优化。 (这是否是一种有用的方法是另一回事)

这个对 collection.isEmpty() 的额外调用可能只是优化循环条件,如果它 JIT 编译为数组上的简单指针递增循环,带有开始和结束指针两者都保存在寄存器中。这是最好的情况,但是额外的源噪声是无用的,无论如何你都会得到。


您可能会争辩说,如果 for (String value : collection) 尚未编译为循环遍历集合的最有效方式,那是编译器 + JVM 的错误,您不应该这样做必须让你的来源丑陋。这在某种程度上可能是正确的,尽管引入对 .isEmpty() 的调用不是编译器或运行时可以做的事情,除非他们可以内联该方法以查看它实际上是在检查与迭代器相同的东西将。但是通过 JIT 编译,一切都可以内联。


TL:DR:一个好的 JIT 编译器很可能不会真正花费任何实际工作来为大多数简单集合创建迭代器,并且没有任何东西可以保存。

在其他情况下,(为了性能)最好不要这样做,除非您的循环通常在空集合上运行,或者(更不可能)创建迭代器在某种程度上非常昂贵。

关于java - 在开始迭代之前检查 Java 集合是否为空有用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26374334/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com