기
단순 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 |