具有无限级数的Java流API性能
我在具有无限级数的Java流API性能,java,performance,lambda,java-8,java-stream,Java,Performance,Lambda,Java 8,Java Stream,我在Java8和新的streamapi中观察到一些特殊的行为 我希望下面两个语句的性能是相同的,但事实并非如此 LongStream.iterate(1, n -> n + 1).limit(5000) .anyMatch(n -> isPerfectCube((n*n*n)+((n*n)*p))); 对 LongStream.iterate(1, n -> n + 1) .anyMatch(n -> isPerfectCube(
Java8
和新的streamapi
中观察到一些特殊的行为
我希望下面两个语句的性能是相同的,但事实并非如此
LongStream.iterate(1, n -> n + 1).limit(5000)
.anyMatch(n -> isPerfectCube((n*n*n)+((n*n)*p)));
对
LongStream.iterate(1, n -> n + 1)
.anyMatch(n -> isPerfectCube((n*n*n)+((n*n)*p)));
这两个语句都应该返回true
,我不希望有任何性能差异,因为它们在找到第一个匹配项时都可能短路。这些语句的唯一区别在于,一个语句在要迭代的数字范围的上限内,而另一个语句则没有
有人能给我解释一下为什么一个会比另一个运行得更快,占用的内存更少吗?有一些
p
的值,其中n
的值越大,情况越是如此。例如,对于p=3
,对于n=50\u 331\u 648
,该条件变为真。在这种情况下,5000的限制当然会在性能方面获胜,但两次计算不会返回相同的结果
我随机选择了一个p
(3002),它在n
小于5000时返回true,结果非常接近(尽管带有限制的版本稍慢,可能是因为附加条件n<5000
)
基准测试结果(每次调用anyMatch
)以微秒为单位:
基准代码(使用jmh):
哪个跑得更快?这很有道理-谢谢。也谢谢你发布微基准
Benchmark Mode Samples Mean Mean error Units
c.a.p.SO24003674.limit avgt 5 130.165 2.663 us/op
c.a.p.SO24003674.noLimit avgt 5 126.876 2.440 us/op
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@State(Scope.Thread)
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
@Fork(1)
public class SO24003674 {
private int p = 3002;
@GenerateMicroBenchmark
public boolean limit() {
return LongStream.iterate(1, n -> n + 1).limit(5000)
.anyMatch(n -> isPerfectCube((n * n * n) + ((n * n) * p)));
}
@GenerateMicroBenchmark
public boolean noLimit() {
return LongStream.iterate(1, n -> n + 1)
.anyMatch(n -> isPerfectCube((n * n * n) + ((n * n) * p)));
}
private static boolean isPerfectCube(long n) {
long tst = (long) (Math.cbrt(n) + 0.5);
return tst * tst * tst == n;
}
}