우리가 IDL에서 대용량 데이터를 처리하는데 있어서는 배열로 정의된 데이터를 다루는 것이 일반적입니다. 즉 대용량의 데이터를 배열에 담고 이러한 배열에 대하여 필요한 연산을 수행하는 방식입니다. 이러한 작업에 있어서는 반복형 구문을 사용하는 연산을 수행하는 경우도 있고 그냥 배열끼리의 연산으로 처리하는 경우도 있습니다. 통상적으로는 배열끼리의 연산으로 처리하는 경우가 많지만 작업의 특성에 따라서는 반복형 구문을 사용하는 연산을 하게 되는 경우도 있습니다. 오늘은 이러한 두가지 연산 방식을 서로 비교해보고 그 차이점도 확인해보고자 합니다. 이를 위하여 간단한 예제를 다음과 같이 작성해봅시다.
n = 10
a = RANDOMU(-1, n)*100
b = RANDOMU(-2, n)*100
c = RANDOMU(-3, n)*100
여기서는 3종의 배열들인 a, b, c를 정의하였는데 각 배열은 0~100의 범위를 갖는 10개의 실수형 값들로 구성됩니다. 이러한 배열들에 대하여 특정한 연산을 수행하는 경우를 가정해봅시다. 예를 들면 다음과 같습니다.
r = a/SQRT(b+c)
이와 같이 배열 a, b, c를 모두 투입하여 배열간 연산을 수행하고 그 결과를 담은 배열 r을 얻었습니다. 이러한 방식의 배열간 연산은 우리가 흔히 하는 작업이고 별로 특별할 것은 없습니다. 결과값들을 살펴보기 위하여 다음과 같이 반복형 구문을 사용하여 출력해봅시다.
FOR j = 0, n-1 DO PRINT, r[j]
출력된 내용을 보면 다음과 같습니다.
0.952586
1.35537
8.34884
5.65442
6.58985
4.02052
7.35813
6.98115
0.181805
2.74484
그러면 이번에는 동일한 작업을 반복형 구문을 사용하는 연산으로 수행해봅시다. 즉 다음과 같은 방식으로 처리하는 것입니다.
r = FLTARR(n)
FOR j = 0, n-1 DO r[j] = a[j]/SQRT(b[j]+c[j])
여기서는 결과값들을 담을 배열 r을 미리 정의한 다음, 반복형 구문을 사용하여 그 내부에서 순차적으로 연산을 수행하고 결과값을 담는 방식으로 처리됩니다. 물론 이러한 방식으로 연산을 수행해도 그 결과는 앞서 배열간 연산으로 얻었던 것과 동일합니다. 즉 배열 r의 값들을 반복형 구문으로 출력해보면 그 내용은 위에서 본 것과 완전히 동일합니다. 따라서 일단 여기까지의 결과를 보면 배열들에 대한 연산에 있어서 배열간 연산과 반복형 구문에 의한 연산 사이에는 별다른 차이가 없고 둘 다 동일한 결과를 생산하는 것으로 보입니다. 그런데 사실은 "아무런 차이가 없다"고 볼 수는 없습니다. 실제로 두 방식 사이에는 연산에 걸리는 시간에 있어서 차이가 존재합니다. 다만 이러한 차이는 배열들의 원소 갯수가 적을 경우에는 거의 나타나지 않습니다. 반대로 얘기하면 배열들의 원소 갯수가 크면 클수록 그 차이가 점점 두드러지게 나타난다고 보면 됩니다.
그러면 이러한 차이를 살펴보기 위해서 앞서 했던 두가지 방식의 연산 각각에 대하여 배열들의 원소 갯수를 대폭 늘리고 연산에 걸리는 시간도 정량적으로 측정해봅시다. 그 과정은 다음과 같습니다.
n = 10000000
a = RANDOMU(-1, n)*100
b = RANDOMU(-2, n)*100
c = RANDOMU(-3, n)*100
TIC
r = a/SQRT(b+c)
TOC
TIC
r = FLTARR(n)
FOR j = 0, n-1 DO r[j] = a[j]/SQRT(b[j]+c[j])
TOC
이와 같이 두가지 방식의 연산 과정들 자체는 그대로이지만 각 연산 과정의 앞뒤에 TIC, TOC 명령을 삽입하여 시간을 측정하도록 하였습니다. 또한 배열들의 원소 갯수를 기존의 10에서 10000000으로 대폭 늘렸습니다. 이렇게 하면 두가지 방식의 연산 각각에 대한 소요시간이 측정되어 출력될 것입니다. 다만 배열들의 원소 갯수가 매우 크므로 매 회차마다 결과값들을 출력하는 과정은 생략하였습니다. 어쨌든 위의 내용을 제 PC의 IDL에서 실행해본 결과는 다음과 같습니다.
% Time elapsed: 0.019999981 seconds.
% Time elapsed: 1.0020001 seconds.
이와 같이 첫번째 방식 즉 배열간 연산의 경우는 0.02초가 걸린 반면 두번째 방식 즉 반복형 구문을 사용한 연산의 경우에는 1.00초 정도가 걸렸습니다. 물론 이러한 수치는 실행할 때마다 다를 수 있고 여러분의 PC에서도 다를 수 있겠지만, 두번째 방식이 시간이 더 걸린다는 것은 변함이 없을 것입니다. 이게 수치상으로는 얼마 안되어 보일 수 있지만 배수로 따지면 두번째 방식이 약 50배 정도 더 느린 셈이므로 상당히 큰 차이입니다. 어쨌든 이러한 비교 결과를 보면 배열간 연산에 비해서 반복형 구문에 의한 연산이 더 많은 시간이 걸린다는 것을 확인할 수 있습니다. 따라서 배열들에 대하여 연산을 수행하고 결과를 얻어야 하는 경우에는 웬만하면 배열간 연산의 방식으로 처리하는 것이 더 효율적이라는 것을 염두에 둘 필요가 있습니다. 물론 반복형 구문을 사용하는 방식으로도 동일한 결과를 얻을 수는 있지만, 데이터의 양이 매우 클 경우에는 시간이 더 걸릴 수 밖에 없다는 점을 유의해야 합니다. 실제로 대용량의 데이터에 대하여 복잡한 연산을 수행하게 될 경우에는 두가지 방식 사이의 차이가 굉장히 크게 나타날 수도 있다는 것을 염두에 둘 필요가 있습니다.
그러면 다음 회차에서는 이러한 차이를 확인할 수 있는 다른 예제를 살펴보도록 하겠습니다.
* 이 글이 도움이 되었다면 게시물에 대하여 공감 버튼(하트 모양) 클릭 및 블로그 구독도 해주시면 더 큰 힘이 됩니다. 감사합니다.
'IDL > Programming' 카테고리의 다른 글
| HttpRequest 클래스의 FILENAME 키워드 사용법 (0) | 2025.08.25 |
|---|---|
| COMPILE_OPT 선언문의 이해 [2] (6) | 2025.07.24 |
| COMPILE_OPT 선언문의 이해 [1] (2) | 2025.07.22 |
| 날짜 기반의 이름을 갖는 파일들에 대한 접근법 (3) | 2025.07.01 |
| FILE_COPY 및 FILE_MOVE 명령 (1) | 2025.06.20 |