본문으로 바로가기

 

단순 1중 반복문 비교는 지난 포스팅에서 실험하였다.

(While / For / Iterator 비교)

 

 

이번에는 반복문들이 중첩될 경우 어느 정도의 속도 차이가 있는지 알아보려고 한다.

먼저 ㅡForFor 와 WhileFor 속도 차이 비교ㅡ가 유의미한지 아래의 코드로 알아보자.

public class WhilevsForLoops {

	public static void main(String[] args) {
		final int trials = 100; // 총 몇 번 테스트할지 갯수
		final int trialsrun = trials - 1;

		boolean[][] speedcount = new boolean[trials][trials];
		int op = 0, ip = 0;

		while (op <= trialsrun) {
			long[][] forloop = new long[trials][trials];
			long[][] whileloop = new long[trials][trials];

			int i, j;
			long systimeaverage = 0;
			long systimenow = System.nanoTime();
			long systimethen = System.nanoTime();
			int whilecount = 0, incount = 0;
			int forcounter = 0, incounter = 0;

			while (whilecount <= trialsrun) {
				for (incount = 0; incount <= trialsrun; incount++) {
					systimenow = System.nanoTime();
					systimethen = System.nanoTime();
					systimeaverage = (systimethen - systimenow);
					whileloop[whilecount][incount] = systimeaverage;
				}
				whilecount++;
			}

			for (forcounter = 0; forcounter <= trialsrun; forcounter++) {
				for (incounter = 0; incounter <= trialsrun; incounter++) {
					systimenow = System.nanoTime();
					systimethen = System.nanoTime();
					systimeaverage = (systimethen - systimenow);
					forloop[forcounter][incounter] = systimeaverage;
				}
			}

			int whilesum = 0;

			for (i = 0; i <= trialsrun; i++) {
				for (j = 0; j <= trialsrun; j++) {
					whilesum += whileloop[i][j];
				}
			}

			int forsum = 0;

			for (i = 0; i <= trialsrun; i++) {
				for (j = 0; j <= trialsrun; j++) {
					forsum += forloop[i][j];
				}
			}

			forsum = forsum / trials;
			whilesum = whilesum / trials;

			for (ip = 0; ip <= trialsrun; ip++) {
				if (whilesum > forsum) {
					speedcount[op][ip] = true;
				} else {
					speedcount[op][ip] = false;
				}
			}
			op++;
		}

		int forloopSpeed = 0;
		int whileloopSpeed = 0;

		for (int k = 0; k <= trialsrun; k++) {
			for (int m = 0; m <= trialsrun; m++) {
				if (speedcount[k][m] == true)
					forloopSpeed++;
				else
					whileloopSpeed++;
			}
		}

		System.out.println("--------------------------------------------------");
		System.out.println("FORFOR 문이  " + forloopSpeed + " 번 더 빨랐습니다");
		System.out.println("WHILEFOR 문이  " + whileloopSpeed + " 번 더 빨랐습니다");
		if (forloopSpeed > whileloopSpeed) {
			System.out.println("forfor가 더 빠른 횟수 : " + (forloopSpeed - whileloopSpeed));
		} else {
			System.out.println("whilefor가 더 빠른 횟수 : " + (whileloopSpeed - forloopSpeed));
		}

	}

}

 

[1차전] ㅡ [100][100]개의 배열, 총 1만번의 테스트 케이스

결과는 이렇게 나왔다.

 

 

이중 반복문 속도 시뮬레이션 

1. 와일포 승리 
FORFOR 문이  4900 번 더 빨랐습니다
WHILEFOR 문이  5100 번 더 빨랐습니다
whilefor가 더 빠른 횟수 : 200

2. 포포 승리
FORFOR 문이  5500 번 더 빨랐습니다
WHILEFOR 문이  4500 번 더 빨랐습니다
forfor가 더 빠른 횟수 : 1000

3. 와일포 승리
FORFOR 문이  4800 번 더 빨랐습니다
WHILEFOR 문이  5200 번 더 빨랐습니다
whilefor가 더 빠른 횟수 : 400

4. 포포 승리
FORFOR 문이  6100 번 더 빨랐습니다
WHILEFOR 문이  3900 번 더 빨랐습니다
forfor가 더 빠른 횟수 : 2200

5. 포포 승리
FORFOR 문이  6000 번 더 빨랐습니다
WHILEFOR 문이  4000 번 더 빨랐습니다
forfor가 더 빠른 횟수 : 2000

6. 와일포 승리
FORFOR 문이  4500 번 더 빨랐습니다
WHILEFOR 문이  5500 번 더 빨랐습니다
whilefor가 더 빠른 횟수 : 1000

7. 와일포 승리
FORFOR 문이  4900 번 더 빨랐습니다
WHILEFOR 문이  5100 번 더 빨랐습니다
whilefor가 더 빠른 횟수 : 200

8. 와일포 승리
FORFOR 문이  4800 번 더 빨랐습니다
WHILEFOR 문이  5200 번 더 빨랐습니다
whilefor가 더 빠른 횟수 : 400

9. 와일포 승리
FORFOR 문이  4600 번 더 빨랐습니다
WHILEFOR 문이  5400 번 더 빨랐습니다
whilefor가 더 빠른 횟수 : 800

10. 포포 승리
FORFOR 문이  5200 번 더 빨랐습니다
WHILEFOR 문이  4800 번 더 빨랐습니다
forfor가 더 빠른 횟수 : 400

1차전 결론    승리횟수   와일포 6 : 포포 4
whilefor 더 빠른 횟수 합산 : 3000번
forfor 더 빠른 횟수 합산 : 5600번

확실히 1중 반복문 for / while의 속도가 비슷한 탓인지

10번의 테스트에서 와일포가 근소한 차이로 승리하기는 했지만

포포의 빠른 횟수가 더 많으므로 1만건의 데이터를 다룬 1차전은 무승부.

 

이번에는 테스트 케이스를 100배 늘려서 보자.

 

[2차전] ㅡ[1000][1000] 개의 배열, 총 100만번의 테스트 케이스ㅡ

코드는 위와 99% 동일하고, 테스트 갯수 변수 trials만 100에서 1000으로 수정하였다.

public class WhilevsForLoops {

	public static void main(String[] args) {
		final int trials = 1000; // 100에서 1000으로 변경.
		final int trialsrun = trials - 1;
	}

 

결과는 아래와 같다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

총 10번 테스트하려했으나 비교 속도가 너무 느려 6번 테스트 후 중단하였음.

 

2차전 결론    승리 횟수   와일포 1 : 포포 5

100만 번의 테스트 케이스, 즉 데이터를 증가시켰더니

ForFor가 압도적으로 더 빨라지기 시작했다. 

2차전 ForFor 압도적 승리.

 

 

실험 결론

데이터가 10만 건 아래일 경우 둘의 속도는 비슷하다. 그러나

10만 건 이상이 될 경우 ForFor가 대체적으로 속도가 우세하였음.

 

 

[부가 실험]

그렇다면, 과연 ForFor의 속도는 WhileFor에 비해 얼마나 더 빠를까?

아래의 코드는 WhileFor와 ForFor의 속도차이를 비교해준다.

public class WhileFor {
	 
	public static int x = 1000;
 	public static int y = 1000; 
	public static double[][] test_data = InputTestData();
	
	 public static void main(String[] args) {
		
	        System.out.print("-- WhileFor -- ");
	        long WfStartTime = System.nanoTime();

	        int i = 0;
	        int j = 0;
	        int length = test_data.length;
	        while (i < length) {
	        	for(j = 0; j < test_data[i].length;j++) {
	        		double v = test_data[i][j];
	        	}
	        i++;
	        }
	        long WfEndTime = System.nanoTime();
	        long Wfelapsed = WfEndTime - WfStartTime;
	        double Wftotaltime = ((double) Wfelapsed) / 1000000000;

	        System.out.print("\n걸린 시간은 "+Wftotaltime+ " 초입니다. \n");
	        System.out.println("-- For For --");
			long FfstartTime = System.nanoTime();

			for (i = 0; i < test_data.length; i++) {
				for (j = 0; j < test_data[i].length; j++) {
					double v = test_data[i][j];
				}
			}
			long FfendTime = System.nanoTime();
			long Ffelapsed = FfendTime - FfstartTime;
			double Fftotaltime = ((double) Ffelapsed) / 1000000000;
		    System.out.println("걸린 시간은 "+Fftotaltime+ " 초입니다." );
		    System.out.println("-------------------------------");
		    if(Wftotaltime > Fftotaltime) {
		    	System.out.println("WhileFor가 " + (Wftotaltime-Fftotaltime) +" 초만큼 더 걸렸습니다.");
		    }
		    else {
		    	System.out.println("ForFor가 " + (Fftotaltime-Wftotaltime) +" 초만큼 더 걸렸습니다.");
		    }
		    
  	}
	
	  public static double[][] InputTestData() {
	       
		  double[][] arr = new double[x][y];
	        int i, j;
	    		
	    	for (i = 0; i < arr.length; i++) {
	        	for(j = 0; j < arr[i].length; j++) {
	        		arr[i][j] = i;
	        	}
	        }
	    	
	        return arr;
	    }
}

 

-- WhileFor -- 
걸린 시간은 0.0052478 초입니다. 
-- For For --
걸린 시간은 0.0024853 초입니다.
-------------------------------
WhileFor가 0.0027625 초만큼 더 걸렸습니다.

 

수행시마다 속도의 차이는 나겠지만,

 

10만건 이상의 테스트시 대부분

ForFor가 0.003초정도 더 빠르다.

 

1초에 1억번의 연산을 하는 컴퓨터이므로,

0.003초정도는 알고리즘 차원에서도 무의미한 퍼포먼스 차이일 수 있겠다..

 

크게 문제가 되지 않는 상황이라면 어느 쪽을 사용하든지 상관없겠으나

많은 데이터를 다루어야 할 경우 whileFor보다는 ForFor를 사용하면 "아주 조금의" 퍼포먼스 향상을 기대할 수 있겠다..

 

'Algorithm > 기타 정보' 카테고리의 다른 글

[java] Stack 구현  (0) 2019.06.26
반복문 비교 (2)  (0) 2019.03.15
반복문 속도 비교 (while, for, iterator)  (3) 2019.03.12