【发布时间】:2023-05-21 20:55:02
【问题描述】:
最近在做微基准测试时,我注意到 CollectionUtils.isNotEmpty 方法消耗了更多时间。我认为我可能有错字或疏忽。我将代码替换为就地检查集合不为空且大小大于零。事实证明它要快得多。
我将方法 CollectionUtils.isNotEmpty 的源代码提取到我的代码中,它也更快。
造成这种差异的原因是什么?
注意:我知道微基准对整个 JVM 优化领域没有帮助。我特意在循环中放了 100 次,如果超过 JVM 就会优化它。检查了Windows和Linux下的代码,性能差异差不多。
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
public class TestCollectionUtilsPerf {
public static void main(String[] args) {
List<String> stringList = Arrays
.asList(new String[] { "StringOne", "StringTwo", "StringThree", "StringFour", "StringFive" });
long startTime = System.nanoTime();
for (int i = 0; i < 100; i++) {
if (stringList != null && stringList.size() != 0) {
continue;
}
}
System.out.format("Manual Inplace Check Time taken is : %d µs %n", (System.nanoTime() - startTime) / 1000);
startTime = System.nanoTime();
for (int i = 0; i < 100; i++) {
if (CollectionUtils.isNotEmpty(stringList)) {
continue;
}
}
System.out.format("Collection Utils Time taken is : %d µs %n", (System.nanoTime() - startTime) / 1000);
startTime = System.nanoTime();
for (int i = 0; i < 100; i++) {
if (isNotEmpty(stringList)) {
continue;
}
}
System.out.format("Manual Method Check Time taken is : %d µs %n", (System.nanoTime() - startTime) / 1000);
}
public static boolean isEmpty(final Collection<?> coll) {
return coll == null || coll.isEmpty();
}
public static boolean isNotEmpty(final Collection<?> coll) {
return !isEmpty(coll);
}
}
输出:
手动就地检查所用时间为:61 µs
收集实用程序所用时间为:237193 µs
手动方法检查时间:66 µs
【问题讨论】:
-
提高性能的最佳方法是禁止空值。一个空集合(或映射或数组)永远不应被视为等同于一个空集合。
-
尝试添加
-XX:+PrintCompilation选项以查看方法是否被编译。 -
学习 JMH,因为任何幼稚的 Java 基准测试都被完全破坏了。对 java 进行基准测试比预期的要困难得多,任何低于一秒的测量都是一个笑话。
-
@maaartinus。谢谢。让我试试看。
标签: java performance microbenchmark