具有无限级数的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;
  }
}