Java 8: производительность потоков против коллекций

Я новичок в Java 8. Я до сих пор не знаю API, но я сделал небольшой неофициальный тест для сравнения производительности нового API Streams и старых добрых коллекций.

Тест состоит в фильтрации спискаIntegerи для каждого четного числа вычислите квадратный корень и сохраните его в результатеList изDouble.

Вот код:

    public static void main(String[] args) {
        //Calculating square root of even numbers from 1 to N       
        int min = 1;
        int max = 1000000;

        List<Integer> sourceList = new ArrayList<>();
        for (int i = min; i < max; i++) {
            sourceList.add(i);
        }

        List<Double> result = new LinkedList<>();


        //Collections approach
        long t0 = System.nanoTime();
        long elapsed = 0;
        for (Integer i : sourceList) {
            if(i % 2 == 0){
                result.add(Math.sqrt(i));
            }
        }
        elapsed = System.nanoTime() - t0;       
        System.out.printf("Collections: Elapsed time:\t %d ns \t(%f seconds)%n", elapsed, elapsed / Math.pow(10, 9));


        //Stream approach
        Stream<Integer> stream = sourceList.stream();       
        t0 = System.nanoTime();
        result = stream.filter(i -> i%2 == 0).map(i -> Math.sqrt(i)).collect(Collectors.toList());
        elapsed = System.nanoTime() - t0;       
        System.out.printf("Streams: Elapsed time:\t\t %d ns \t(%f seconds)%n", elapsed, elapsed / Math.pow(10, 9));


        //Parallel stream approach
        stream = sourceList.stream().parallel();        
        t0 = System.nanoTime();
        result = stream.filter(i -> i%2 == 0).map(i -> Math.sqrt(i)).collect(Collectors.toList());
        elapsed = System.nanoTime() - t0;       
        System.out.printf("Parallel streams: Elapsed time:\t %d ns \t(%f seconds)%n", elapsed, elapsed / Math.pow(10, 9));      
    }.

И вот результаты для двухъядерного компьютера:

    Collections: Elapsed time:   94338247 ns    (0,094338 seconds)
    Streams: Elapsed time:       201112924 ns   (0,201113 seconds)
    Parallel streams: Elapsed time:  357243629 ns   (0,357244 seconds)

Для этого конкретного теста потоки примерно в два раза медленнее, чем коллекции, и параллелизм не помогает (или я использую его неправильно?).

Вопросы:

Справедлив ли этот тест? Я сделал какую-нибудь ошибку?Потоки медленнее коллекций? Кто-нибудь сделал хороший формальный тест на это?К какому подходу я должен стремиться?

Обновленные результаты.

Я выполнил тест 1к раз после прогрева JVM (1к итераций), как советовал @pveentjer:

    Collections: Average time:      206884437,000000 ns     (0,206884 seconds)
    Streams: Average time:           98366725,000000 ns     (0,098367 seconds)
    Parallel streams: Average time: 167703705,000000 ns     (0,167704 seconds)

В этом случае потоки более производительны. Интересно, что будет наблюдаться в приложении, где функция фильтрации вызывается только один или два раза во время выполнения.

Ответы на вопрос(4)

Ваш ответ на вопрос