LoginSignup
0
0

新旧速度対決

Last updated at Posted at 2019-11-15

##速度対決
新旧じゃないのもありますw
主にループ処理について、速度対決しました。
最高3回まで勝負しました。

##sizeとisEmpty

ListSize.java
package test;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.IntStream;

/**
 * Test.
 *
 * @author me
 *
 */
public class ListSizeTest {
	/**
	 * 計測.
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println("-----size-----");
		Long start1 = System.nanoTime();
		loop1();
		Long end1 = System.nanoTime();
		System.out.println(end1 - start1 + "ns\r\n\r\n-----isEmpty-----");
		Long start2 = System.nanoTime();
		loop2();
		Long end2 = System.nanoTime();
		System.out.println(end2 - start2 + "ns");
	}
	/**
	 * size
	 */
	private static void loop1() {
		List<Integer> list = new LinkedList<Integer>();
		IntStream.range(0, 100000).forEach(i -> list.add(0));
		if (list.size() == 0) {

		}
	}
	/**
	 * isEmpty
	 */
	private static void loop2() {
		List<Integer> list = new LinkedList<Integer>();
		IntStream.range(0, 100000).forEach(i -> list.add(0));
		if (list.isEmpty()) {

		}
	}

	/**
	 * -----size-----
	 * 48341618ns
	 *
	 * -----isEmpty-----
	 * 10812354ns
	 */
}


isEmptyの圧勝ですね
ArrayListかつまじで要素数知りたいような仕方ない場合以外はなるべく使いたくないsize

##指定回数のループ

forとIntStream.java
package test;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.IntStream;

/**
 * Test.
 *
 * @author me
 *
 */
public class LoopTest1 {
	/**
	 * 計測.
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println("-----for文-----");
		Long start1 = System.nanoTime();
		loop1();
		Long end1 = System.nanoTime();
		System.out.println(end1 - start1 + "ns\r\n\r\n-----IntStream-----");
		Long start2 = System.nanoTime();
		loop2();
		Long end2 = System.nanoTime();
		System.out.println(end2 - start2 + "ns");
	}
	/**
	 * for文
	 */
	private static void loop1() {
		List<Integer> list = new LinkedList<Integer>();
		for (int i = 0; i < 10000000; i++) {
			list.add(0);
		}
	}
	/**
	 * IntStream
	 */
	private static void loop2() {
		List<Integer> list = new LinkedList<Integer>();
		IntStream.range(0, 10000000).forEach(i -> list.add(0));
	}
	/**
	 * -----for文-----
	 * 1563850086ns
	 * 1563641080ns
	 * 1802331635ns
	 *
	 * -----IntStream-----
	 * 1809124813ns
	 * 1726875157ns
	 * 1476842733ns
	 */
}

んーどうなんだろ...
まぁがっちり検証してるわけじゃないですけど、なんだかんだただのfor文のがいいのかもですね
可読性はIntStreamのが高そうですけど
どちらかというとstreamの中間操作ででてくるのかな?

##拡張for文とstream

これぞ本命

拡張for文とstream.java
package test;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.IntStream;

/**
 * Test.
 *
 * @author me
 *
 */
public class LoopTest2 {
	/**
	 * 計測.
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println("-----for文-----");
		Long start1 = System.nanoTime();
		loop1();
		Long end1 = System.nanoTime();
		System.out.println(end1 - start1 + "ns\r\n\r\n-----stream-----");
		Long start2 = System.nanoTime();
		loop2();
		Long end2 = System.nanoTime();
		System.out.println(end2 - start2 + "ns");
	}
	/**
	 * for文
	 */
	private static void loop1() {
		List<Integer> list = new LinkedList<Integer>();
		IntStream.range(0, 10000000).forEach(i -> list.add(0));
		for(Integer num : list) {
			num += 1;
		}
	}
	/**
	 * stream
	 */
	private static void loop2() {
		List<Integer> list = new LinkedList<Integer>();
		IntStream.range(0, 10000000).forEach(i -> list.add(0));
		list.stream().map(num -> num += 1);
	}
	/**
	 * -----for文-----
	 * 1746784426ns
	 * 1855868091ns
	 * 1790482647ns
	 *
	 * -----stream-----
	 * 1453116296ns
	 * 1630589874ns
	 * 1487128838ns
	 */
}

どっかの記事で、ループ回数が少なければstream,おおけれfor文みたいなの見たことあります
まぁstreamでいいのでは、たのしいし

##forと拡張for

for文と拡張for文.java
package test;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.IntStream;

/**
 * Test.
 *
 * @author me
 *
 */
public class LoopTest3 {
	/**
	 * 計測.
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println("-----for文-----");
		Long start1 = System.nanoTime();
		loop1();
		Long end1 = System.nanoTime();
		System.out.println(end1 - start1 + "ns\r\n\r\n-----拡張for文-----");
		Long start2 = System.nanoTime();
		loop2();
		Long end2 = System.nanoTime();
		System.out.println(end2 - start2 + "ns");
	}
	/**
	 * for文List#get()
	 */
	private static void loop1() {
		List<Integer> list = new LinkedList<Integer>();
		IntStream.range(0, 100000).forEach(i -> list.add(0));
		for (int i = 0; i < list.size(); i++) {
			int a = list.get(i);
		}
	}
	/**
	 * 拡張for文
	 */
	private static void loop2() {
		List<Integer> list = new LinkedList<Integer>();
		IntStream.range(0, 100000).forEach(i -> list.add(0));
		for (Integer num : list) {
			int a = num;
		}
	}
	/**
	 * -----for文-----
	 * 5172240485ns
	 *
	 * -----拡張for文-----
	 * 25571106ns
	 */
}

はい。拡張for文を使えない状況ってあんまないだろうし
拡張for文さすがって感じですね。

##中間操作ありのループ

中間処理ありのループ.java
package test;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * Test.
 *
 * @author me
 *
 */
public class LoopTest4 {
	/**
	 * 計測.
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println("-----for文-----");
		Long start1 = System.nanoTime();
		loop1();
		Long end1 = System.nanoTime();
		System.out.println(end1 - start1 + "ns\r\n\r\n-----stream-----");
		Long start2 = System.nanoTime();
		loop2();
		Long end2 = System.nanoTime();
		System.out.println(end2 - start2 + "ns");
	}
	/**
	 * for文
	 */
	private static void loop1() {
		List<String> list = new LinkedList<String>();
		IntStream.range(0, 5000000).forEach(v -> list.add("a"));
		IntStream.range(0, 5000000).forEach(v -> list.add("z"));
		List<String> answer = new LinkedList<String>();
		for (String str : list) {
			if (str.equals("a")) {
				answer.add(str);
			}
		}
	}
	/**
	 * stream
	 */
	private static void loop2() {
		List<String> list = new LinkedList<String>();
		IntStream.range(0, 5000000).forEach(v -> list.add("a"));
		IntStream.range(0, 5000000).forEach(v -> list.add("z"));
		list.stream().filter(v -> v.equals("a")).collect(Collectors.toList());
	}
	/**
	 * -----for文-----
	 * 2954071288ns
	 * 2845232552ns
	 * 2849512987ns
	 *
	 * -----stream-----
	 * 2036753887ns
	 * 2563286049ns
	 * 2188877495ns
	 */
}

中間操作の中身にもよると思うし一概には言えなさそうな感じだけれど
まぁstreamなのでは?

##メソッドとfunction

メソッドとfunction.java
package test;

import java.util.LinkedList;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.IntStream;

/**
 * Test
 * @author me
 *
 */
public class MethodFunctionTest1 {
	/**
	 * 計測
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println("-----method-----");
		Long start1 = System.nanoTime();
		method();
		Long end1 = System.nanoTime();
		System.out.println(end1 - start1 + "ns\r\n\r\n-----function-----");
		Long start2 = System.nanoTime();
		function.get();
		Long end2 = System.nanoTime();
		System.out.println(end2 - start2 + "ns");
	}
	/**
	 * method
	 */
	private static List<String> method() {
		List<String> list = new LinkedList<String>();
		IntStream.range(0, 10000000).forEach(i -> list.add("a"));
		return list;
	}
	/**
	 * function
	 */
	private static Supplier<List<String>> function = () -> {
		List<String> list = new LinkedList<String>();
		IntStream.range(0, 10000000).forEach(v -> list.add("a"));
		return list;
	};
	/**
	 * -----method-----
	 * 1766534141ns
	 * 1802412812ns
	 * 1645580959ns
	 *
	 * -----function-----
	 * 1560679066ns
	 * 1584875301ns
	 * 1897649797ns
	 */
}

これがほんとにわからん
メモリへの負荷だとかでfunctionの使い方が変だとダメらしいし
functionって何のためにあるんだろう
まじでstreamの中間操作のためなのかな

まぁメソッドでいいですねって結果ですかね

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0