오늘은 IDL의 반복형 구문인 FOR문에서 반복 회차를 제어하는데 있어서 CONTINUE와 BREAK 명령을 사용하는 방법 및 두 명령 사이의 차이점에 대하여 소개해볼까 합니다. 설명을 위하여 기본적인 FOR문이 담긴 프로그램을 다음과 같이 작성해 보았습니다. 보시는 것처럼 제어변수인 j가 0으로 시작하여 10으로 끝날 때까지 총 11회에 걸쳐 반복이 수행되며, 매 회차마다 두 개의 PRINT문이 실행됩니다.따라서 매 회차마다 두 줄의 출력 결과가 나오도록 되어 있습니다.
PRO test_for_loop
FOR j = 0, 10 DO BEGIN
PRINT, 'working with j =', j
PRINT, j*10., j/10.
ENDFOR
END
이 프로그램을 실행하면 그 결과는 다음과 같습니다. 매 회차마다 두 줄이 출력되며 이 작업이 11회에 걸쳐 반복되므로 총 22줄의 출력 결과를 얻게 됩니다.
working with j = 0
0.00000 0.00000
working with j = 1
10.0000 0.100000
working with j = 2
20.0000 0.200000
working with j = 3
30.0000 0.300000
working with j = 4
40.0000 0.400000
working with j = 5
50.0000 0.500000
working with j = 6
60.0000 0.600000
working with j = 7
70.0000 0.700000
working with j = 8
80.0000 0.800000
working with j = 9
90.0000 0.900000
working with j = 10
100.000 1.00000
이제 반복문 안에서 CONTINUE 명령을 사용해보겠습니다. 다음과 같이 두 PRINT문 사이에 IF 구문의 형태로 CONTINUE 명령을 삽입하였습니다.
PRO test_for_loop
FOR j = 0, 10 DO BEGIN
PRINT, 'working with j =', j
IF j GT 5 THEN CONTINUE
PRINT, j*10., j/10.
ENDFOR
END
반복형 구문 안에서 CONTINUE 명령이 등장하면 거기서 바로 다음 반복 회차로 넘어가게 됩니다. 즉 CONTINUE 뒤에 있는 작업은 무시하고 바로 다음 회차로 넘어가도록 하는 역할을 합니다. 여기서는 j가 5보다 크면 CONTINUE 명령이 실행되도록 했기 때문에, j의 값이 0~5일 경우에는 원래대로 회차당 두번씩 출력을 하지만, j의 값이 6~10일 경우에는 두번째 PRINT문을 실행하지 않고 바로 다음 회차로 넘어가게 됩니다. 따라서 이 프로그램의 실행 결과는 다음과 같습니다.
working with j = 0
0.00000 0.00000
working with j = 1
10.0000 0.100000
working with j = 2
20.0000 0.200000
working with j = 3
30.0000 0.300000
working with j = 4
40.0000 0.400000
working with j = 5
50.0000 0.500000
working with j = 6
working with j = 7
working with j = 8
working with j = 9
working with j = 10
즉 처음 6회 동안은 두번씩 출력을 하고 그 다음 5회 동안은 한번씩 출력을 하므로, 총 17회의 출력이 진행된 것입니다. 이와 같은 방식으로 CONTINUE를 사용하여 반복 작업의 세부 흐름을 제어할 수 있습니다. 특히 위 예제와 같이 조건문과 함께 CONTINUE를 사용하면 반복 작업을 하는데 있어서 조건에 따라 매 회차당 어느 정도의 작업만 할 것인지를 조절하는 것이 가능합니다.
그런데 CONTINUE 대신 BREAK 명령을 사용하면 어떻게 될까요? 설명에 앞서 위 예제 프로그램을 다음과 같이 수정해서 실행해 봅시다. 즉 CONTINUE 대신 BREAK가 사용되도록 수정하여 실행해보고 그 차이를 보기 위해서입니다.
PRO test_for_loop
FOR j = 0, 10 DO BEGIN
PRINT, 'working with j =', j
IF j GT 5 THEN BREAK
PRINT, j*10., j/10.
ENDFOR
END
이 상태로 프로그램을 실행한 결과는 다음과 같습니다. 앞서 CONTINUE를 사용했을 경우와의 차이가 보이시나요?
working with j = 0
0.00000 0.00000
working with j = 1
10.0000 0.100000
working with j = 2
20.0000 0.200000
working with j = 3
30.0000 0.300000
working with j = 4
40.0000 0.400000
working with j = 5
50.0000 0.500000
working with j = 6
사실 BREAK 명령의 역할은 CONTINUE보다 좀 더 강하다고 볼 수 있는데요. CONTINUE는 이후의 내용을 무시하고 다음 회차로 넘어가라는 의미였지만, BREAK는 그냥 그 자리에서 반복 루프 자체를 아예 박차고 나오라는 의미입니다. 프로그램의 내용을 보면 j가 5보다크면 반복 루프를 아예 빠져나오도록 되어 있습니다. 따라서 j의 값이 0~5일 경우에는 정상적으로 두번씩 출력을 하지만, j의 값이 5보다큰 6이 된 회차에서는 출력 한번만 한 상태에서 바로 빠져나온 셈입니다. 따라서 총 13회에 걸쳐 출력이 진행된 것을 볼 수 있습니다.
사실 위의 두 케이스를 비교해보면 CONTINUE와 BREAK 사이의 차이점이 분명하게 드러납니다. 비유가 적절한지 모르겠으나, 반복 루프 자체를 하나의 직장으로 비유한다면 CONTINUE는 조퇴에 해당되고 BREAK는 퇴사에 해당된다고 보면 됩니다. 따라서 BREAK 명령은 CONTINUE 명령보다는 좀 더 신중하게 사용해야 한다고 볼 수 있습니다. 어쨌든 애초에 반복횟수가 정해진 작업이라 하더라도 조건에 따라 어느 정도 횟수만큼만 작업을 진행한 후 그 이후 회차는 그냥 넘겨야 하는 경우에는 위와 같이 CONTINUE 또는 BREAK 명령을 사용하여 실질 반복 횟수를 조정할 수 있습니다. 그런데 반복횟수가 많고 매 회차마다 반복해야 할 작업이 규모가 좀 있는 경우에는, 전체 작업 소요시간에 있어서 차이가 커질 수도 있는데요. 다음과 같이 반복횟수를 크게 늘리고 전체 작업 소요시간을 측정할 수 있도록 프로그램을 수정해 봅시다.
PRO test_for_loop
TIC
FOR j = 0, 10000 DO BEGIN
PRINT, 'working with j =', j
IF j GT 5000 THEN CONTINUE
PRINT, j*10., j/10.
ENDFOR
TOC
END
이 프로그램에서는 j가 0부터 10000까지 총 10001회에 걸쳐 반복이 진행되지만, j가 5000보다 커지는 순간부터는 CONTINUE가 실행되도록 하였습니다. 사실 매 회 출력을 하게 되므로 횟수가 크면 시간이 약간은 걸립니다. 제 컴퓨터에서는 평균적으로 약 6.9초 정도가 걸렸습니다. 그런데 위 프로그램에서 다음과 같이 CONTINUE를 BREAK로 바꿔서 실행해 봅시다.
PRO test_for_loop
TIC
FOR j = 0, 10000 DO BEGIN
PRINT, 'working with j =', j
IF j GT 5000 THEN BREAK
PRINT, j*10., j/10.
ENDFOR
TOC
END
이 때 제 컴퓨터에서는 평균적으로 약 4.8초 정도가 걸렸습니다. 즉 CONTINUE를 사용했을 때보다 BREAK를 사용했을 때 소요시간이 덜 걸렸다는 얘기입니다. CONTINUE는 어떻게든 모든 반복 회차를 소화하는 반면, BREAK는 반복 루프를 아예 빠져나오기 때문에 아무래도 전체 작업에 있어서는 CONTINUE가 시간이 좀 더 걸릴 수 밖에 없습니다. 반복횟수의 크기 및 반복 회차별 작업의 규모 등에 따라 이러한 차이는 꽤 커질 수도 있습니다. 이러한 점을 고려하여 CONTINUE 또는 BREAK 중 하나를 적절히 선택하여 사용하면 대규모 반복 작업의 효율을 높일 수도 있다는 점을 염두에 두면 좋을 것 같습니다.
'IDL > Programming' 카테고리의 다른 글
IDL Task 소개 (Part 2) (0) | 2018.05.10 |
---|---|
IDL Task 소개 (Part 1) (0) | 2018.05.04 |
포맷 코드 사용 관련 유용한 팁 하나 소개 (0) | 2017.07.10 |
인덱스 기반의 배열의 생성에 관하여 (0) | 2017.04.07 |
텍스트 파일을 쓰는 방법에 관하여 (0) | 2016.12.27 |