package com.cbooy.cakes.java8.pt;

import com.google.common.collect.Lists;
import org.junit.Test;

import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * Created by haoc.
 */
public class PerformanceTest4Simple {

    /**
     * 循环10000000次
     * 4 毫秒
     */
    @Test
    public void testFor() throws InterruptedException {
        Instant start = Instant.now();

        for (int i = 0; i < 10000000; i++) {

        }

        Instant end = Instant.now();
        long millis = Duration.between(start, end).toMillis();
        System.out.println(millis);
    }

    /**
     * 循环10000000次
     * 131 毫秒
     */
    @Test
    public void testStream() throws InterruptedException {
        Instant start = Instant.now();

        IntStream.range(0, 10000000).forEach(i -> {

        });

        Instant end = Instant.now();
        long millis = Duration.between(start, end).toMillis();
        System.out.println(millis);
    }

    /**
     * 循环10000000次
     * 179 毫秒
     */
    @Test
    public void testParallelStream() throws InterruptedException {
        Instant start = Instant.now();

        IntStream.range(0, 10000000).parallel().forEach(i -> {

        });

        Instant end = Instant.now();
        long millis = Duration.between(start, end).toMillis();
        System.out.println(millis);
    }

    /**
     * 循环10000000次
     * 5188 毫秒
     */
    @Test
    public void testForListCreate() {
        Instant start = Instant.now();

        ArrayList<Object> arrayList = Lists.newArrayList();
        for (int i = 0; i < 10000000; i++) {
            arrayList.add(new Object());
        }

        Instant end = Instant.now();
        long millis = Duration.between(start, end).toMillis();
        System.out.println(millis);
    }

    /**
     * 循环10000000次
     * 5129 毫秒
     */
    @Test
    public void testStreamListCreate() {
        Instant start = Instant.now();

        List<Object> objectList = IntStream.range(0, 10000000)
                .boxed()
                .map(i -> new Object())
                .collect(Collectors.toList());

        Instant end = Instant.now();
        long millis = Duration.between(start, end).toMillis();
        System.out.println(millis);
    }

    /**
     * 循环10000000次
     * 3127 毫秒
     */
    @Test
    public void testParallelStreamListCreate() {
        Instant start = Instant.now();

        List<Object> objectList = IntStream.range(0, 10000000)
                .parallel()
                .boxed()
                .map(i -> new Object())
                .collect(Collectors.toList());

        Instant end = Instant.now();
        long millis = Duration.between(start, end).toMillis();
        System.out.println(millis);
    }

    /**
     * 循环10000000次
     * 8841 毫秒
     */
    @Test
    public void testForLinkedListCreate() {
        Instant start = Instant.now();

        LinkedList<Object> arrayList = Lists.newLinkedList();
        for (int i = 0; i < 10000000; i++) {
            arrayList.add(new Object());
        }

        Instant end = Instant.now();
        long millis = Duration.between(start, end).toMillis();
        System.out.println(millis);
    }

    /**
     * 循环10000000次
     * 8396 毫秒
     */
    @Test
    public void testStreamLinkListCreate() {
        Instant start = Instant.now();

        LinkedList<Object> objectList = IntStream.range(0, 10000000)
                .boxed()
                .map(i -> new Object())
                .collect(Collectors.toCollection(LinkedList::new));

        Instant end = Instant.now();
        long millis = Duration.between(start, end).toMillis();
        System.out.println(millis);
    }

    /**
     * 循环10000000次
     * 10469 毫秒
     */
    @Test
    public void testParallelStreamLinkListCreate() {
        Instant start = Instant.now();

        LinkedList<Object> objectList = IntStream.range(0, 10000000)
                .parallel()
                .boxed()
                .map(i -> new Object())
                .collect(Collectors.toCollection(LinkedList::new));

        Instant end = Instant.now();
        long millis = Duration.between(start, end).toMillis();
        System.out.println(millis);
    }

    /**
     * 循环10000000次
     * 15 毫秒
     */
    @Test
    public void testForListLoop1() {
        ArrayList<Object> arrayList = Lists.newArrayList();
        for (int i = 0; i < 10000000; i++) {
            arrayList.add(new Object());
        }

        Instant start = Instant.now();

        for (Object o : arrayList) {
            o.getClass();
        }

        Instant end = Instant.now();
        long millis = Duration.between(start, end).toMillis();
        System.out.println(millis);
    }

    /**
     * 循环10000000次
     * 12 毫秒
     */
    @Test
    public void testForListLoop2() {
        ArrayList<Object> arrayList = Lists.newArrayList();
        for (int i = 0; i < 10000000; i++) {
            arrayList.add(new Object());
        }

        Instant start = Instant.now();

        for (int i = 0, len = arrayList.size(); i < len; i++) {
            arrayList.get(i).getClass();
        }

        Instant end = Instant.now();
        long millis = Duration.between(start, end).toMillis();
        System.out.println(millis);
    }

    /**
     * 循环10000000次
     * 64 毫秒
     */
    @Test
    public void testStreamListLoop() {
        ArrayList<Object> arrayList = Lists.newArrayList();
        for (int i = 0; i < 10000000; i++) {
            arrayList.add(new Object());
        }

        Instant start = Instant.now();

        arrayList.forEach(Object::getClass);

        Instant end = Instant.now();
        long millis = Duration.between(start, end).toMillis();
        System.out.println(millis);
    }

    /**
     * 循环10000000次
     * 124 毫秒
     */
    @Test
    public void testParallelStreamListLoop() {
        ArrayList<Object> arrayList = Lists.newArrayList();

        for (int i = 0; i < 10000000; i++) {
            arrayList.add(new Object());
        }

        Instant start = Instant.now();

        arrayList.parallelStream().forEach(Object::getClass);

        Instant end = Instant.now();
        long millis = Duration.between(start, end).toMillis();
        System.out.println(millis);
    }

}