[출처 : http://bufferoverflow.tistory.com/tag/포인터%20배열%20속도]


우선 배열의 경우에는

시작주소( 배열명칭) + sizeof( 데이타형 ) * 인덱스

와 같은 수식으로 
계산됩니다.


 
여기서   '+' 연산자의 앞부분은 일정하고  뒷부분에서  인덱스만 변하여

계산을 하는데  어셈블리어나 기계어로 번역될 때의 자세한 상태를 보지 아니해도

+ 연산자를 전후로 대략 두개의 피연산자을 동반합니다.

ADD operand1 operand2  이고

operand2는 다시 곱셈에서 얻어지므로 대략  

MUL operand2 operand3  와 같습니다



그리고 포인터에 의한 주소연산에서는  
시작시에  pa를 시작주소를 설정하고나서

이 하나의 피연산자에 대하여만 연산을 하게됩니다.

 

그래서 

INC operand1

기계어로 번역될 때 명령코드도 간단하게되므로 메모리도 절약되지만

덧셈의 연산에 비하여 속도가 차이가 납니다.

굳이 어려운 포인터를 사용하는 이유가 있다고 봅니다.

 

좀더 자세히 설명을 한다면

arr[i] = ?  와 같은 배열문장은 배열의 i 인덱스 요소에 ?라는 값을 대입하라는 

의미입니다. 

값을 대입하기 위하여는 우선 그 주소로 이동하기 위하여 주소연산을 하게됩니다.

 

arr[i] = ? 에서 배열의 '[i]'연산자는  *( arr + i ) = ? 와 같은 표현식으로

간주되는 데  (arr + i )는 arr라는 배열의 이름( 상수의 주소값 )에 

정수를 더하여 그 주소를 계산하라는 의미이고 

'*' 연산자는  arr가 data라는 구조체형의 포인터이므로 그 주소에서 data라는 구조체형의 크기 공간에 있는 내용물을 ? 라는 값으로 채워라는 뜻입니다.

 

여기서 포인터 연산의 정수 덧셈은 arr라는 주소값에 sizeof( data ) * i의

바이트 수를  더하게 됩니다.

매번 i라는 배열요소의 인덱스가 변할 때 마다 내부적으로는

( 시작주소 + 데이타형의 크기 * 인덱스 )라는 주소계산을 합니다.

 

반면에 포인터를 사용하는 경우에는  

*pa = ?; 

pa++; 에서

 

*pa = ? 는 현재의 pa라는 주소에 data형의  크기공간안의 내용을 ? 라는 값으로

채워라는 의미입니다.

pa++; 는 다음  요소에 접근하기 위한 주소연산을 하는 문장입니다.

 

pa++ 연산은 배열의 '[]'연산자를 사용하는 경우와는 달리  

pa + sizeof( data );  와 같은 계산으로 주소값을 계산하게됩니다.

 

즉 현재의 요소가 위치하는 pa라는  주소에  다음 주소로 옮기기 위하여

구조체형의 크기만큼의 바이트수를 더하여 얻는 주소값으로 계산됩니다..

 

기계코드로 번역될 때   sizeof( data ) * i  와 같은 곱셈연산은 많은 시간을

소모하는 것으로 알려져있습니다.

그래서 배열을 사용하는 것은 프로그래머의 입장에서는 사용하기 편하고 쉽게

인식하지만 기계코드를 전환될 때는 후자의 포인터를 사용할 때 만큼의

속도를 얻지 못합니다.

 

물론 소수의 배열요소들에 접근하여 작업하는 경우야 눈에 띄는 

차이를 느끼기 어렵겠지만  방대한 DB에서 어떤 데이타를 검색한다던지

할 때를 생각해보시면 짐작할 수  있을 것입니다.

 

반면에 포인터는 학습하는데 대체로 많은 수고를 요구하거나 디버깅을 할 때

쉽지 아니하지만. 배열을 사용할 때보다도 실행속도에서는 빠른다는 장점이 있으므로

각각의 장단점이 있습니다.

    

보통 포인터 식이라고 할때   arr[i]를   *(arr + i )를 고치는 것을 포인터식이라고

말하기도 하는 데  이것은 내부적으로 는 같은 코드를 생성하므로 같은 표현식으로

보아야하고 순수한 포인터 연산에 의한 코드 작성은 포인터의 단항연산자를 사용하여
 
배열의 요소로 이동하면서 필요한 연산을 

수행하는 경우라고 봅니다.

+ Recent posts