Java 8流比手写循环慢吗?

时间:2018-04-21 10:16:02

标签: java performance java-8 java-stream

我正在尝试对Java函数的两个不同实现进行基准测试,以检查数字是否包含至少一个偶数位。第一个实现使用手写循环,而第二个实现使用stream

public class StreamTest {

public boolean containsEvenDigit(int n) {
    char [] digits = String.valueOf(n).toCharArray();
    for(char d : digits) {
        if(d % 2 == 0) {
            return true;
        }
    }
    return false;
}

public boolean containsEvenDigitStreams(int n) {
    return String.valueOf(n).chars().anyMatch(i -> i % 2 == 0);
}

public static void main(String[] args) {
    System.out.println("============WITHOUT STREAM============");
    long start1 = System.nanoTime();
    for(int i = 0 ; i < 1_000_000; i++) {
        (new StreamTest()).containsEvenDigit(11215 + i);
    }
    long duration1 = (long)(System.nanoTime() - start1)/1_000_000;
    System.out.println("Duration : " + duration1 + " milliseconds.");
    System.out.println();

    System.out.println("============USING STREAM============");
    long start2 = System.nanoTime();
    for(int i = 0 ; i < 1_000_000; i++) {
        (new StreamTest()).containsEvenDigitStreams(11215 + i);
    }
    long duration2 = (long)(System.nanoTime() - start2)/1_000_000;
    System.out.println("Duration : " + duration2 + " milliseconds.");
    System.out.println();

}

}

main函数中,我没有输出正在测试的函数的返回值以消除I / O开销。结果表明,使用流的实现比使用循环的实现要慢得多。

============WITHOUT STREAM============
Duration : 119 milliseconds.

============USING STREAM============
Duration : 771 milliseconds.

这是否意味着Java 8个流比手写循环慢?

更新:我现在正在使用JMH对这两个功能进行基准测试。

public class MyBenchmark {

private boolean containsEvenDigit(int n) {
    char [] digits = String.valueOf(n).toCharArray();
    for(char d : digits) {
        if(d % 2 == 0) {
            return true;
        }
    }
    return false;
}

private boolean containsEvenDigitStream(int n) {
    return String.valueOf(n).chars().anyMatch(i -> i % 2 == 0);
}

@State(Scope.Thread)
public static class MyState{
    public int x = 1_357_997_531;
}

@Benchmark
public void testLoop(MyState state, Blackhole blackhole) {
    boolean retVal = containsEvenDigit(state.x);
    blackhole.consume(retVal);
}

@Benchmark
public void testStream(MyState state, Blackhole blackhole) {
    boolean retVal = containsEvenDigitStream(state.x);
    blackhole.consume(retVal);
}

public static void main(String[] args) throws RunnerException {
    Options opt = new OptionsBuilder()
            .include(MyBenchmark.class.getSimpleName())
            .forks(1)
            .build();

    new Runner(opt).run();
}

}

这次手写循环也以大约8的顺序击败了流。 这是结果摘要。

Benchmark                Mode  Cnt        Score        Error  Units
MyBenchmark.testLoop    thrpt  200  3578620.170 ± 207106.919  ops/s
MyBenchmark.testStream  thrpt  200   433884.589 ±  23993.270  ops/s

0 个答案:

没有答案