确认for循环和流性能的JMH基准测试的有效性

时间:2019-03-25 17:02:00

标签: java java-stream jmh

我决定要对简单流操作进行一些测量,并将它们与相应的流前迭代结构进行比较。

我有一个特定长度的ArrayList,这样所有列表元素都是三个字符的字符串。

以下是与此相关的基准测试方法:

@Benchmark
public long shortLengthConstantSizeFor() {
    long count   = 0;
    for (String val : shortLengthListConstantSize) {
        if (val.length() == 3) { ++ count; }
    }
    return count;
}

@Benchmark
public long shortLengthConstantSizeForEach() {
    IntHolder   intHolder   = new IntHolder();
    shortLengthListConstantSize.forEach(s -> { if (s.length() == 3) ++ intHolder.value; } );
    return intHolder.value;
}

@Benchmark
public long shortLengthConstantSizeLambda() {
    return shortLengthListConstantSize.stream().filter(s -> s.length() == 3).count();
}

@Benchmark
public long shortLengthConstantSizeLambdaParallel() {
    return shortLengthListConstantSize.stream().parallel().filter(s -> s.length() == 3).count();
}

我要向社区确认的仅仅是这些功能是否“等效”,并且将真正衡量它们看上去要衡量的内容。我不在这里提供测量值,因为那样会分散注意力。

请注意,“ shortLength”是指“短列表”。我也有这些方法的几个块,具有不同的长度列表,最多有300k个元素。

1 个答案:

答案 0 :(得分:0)

如果用“功能对等”来表示每种方法执行相同的功能或测量,包括副作用-看来是这样。

一个人可能会争辩说,在第二种方法中,您应该使用LongHolder而不是IntHolder来匹配函数的共域。但是,实际上,如果您的“值”是该课程中的long,那么它就是通行证。

值得一提的是,count()只是map(x -> 1L).sum()的简写,但对于此基准测试没有任何改变。