Array.indexOf(), 또는 Vector.<T>.indexOf()의 성능이 불만족스러울 때, Dictionary를 이용하면 좋다.
문제 상황
최근 실험중인 아키텍처를 시뮬레이션 하기 위해, 동일 Vector 내 n 개의 임의의 아이템에 대해 단방향 링크를 가지는 1,000,000 크기의 Vector를 생성한 후, 역시 임의로 선택한 아이템으로을 기점으로 너비 우선 탐색(그래프)을 실행하였다.
그런데, 이를 수행함에 있어 성능이 상당히 떨어지는 것을 확인하였고, 프로파일링 결과 Vector.indexOf()가 병목 지점인 것을 확인하였다. (해당 지점을 이미 방문한 적이 있는지 확인하는 부분을 if (myVector.indexOf(item) < 0) 과 같이 구현하였다.)
구세주 Dictionary
다행히, ActionScript에는 Dictionary라는 클래스가 있다. 일반적인 Object와는 다르게, 인스턴스의 레퍼런스를 key 값으로 직접 참조할 수 있다. 예를 들면, myDict[obj] 의 경우, 일반 Object는 이를 myDict[obj.toString()] 으로 해석하나, Dictionary는 그러한 과정을 거치지 않고, 그 인스턴스의 레퍼런스 자체를 참조한다. 즉, 키 값 비교에 strict equality(===)를 사용한다.1
또한, Vector.indexOf()나 Array.indexOf()는 배열의 크기에 따라 성능이 달라지는 특징이 있으나, Dictionary는 등록된 프로퍼티의 수에 따라 성능에 큰 차이를 보이진 않는다. 그리고, 현재 버전의 Flash Player에서 그 성능이 Array.indexOf() 나 Vector.indexOf() 에 비해 매우 빠르다.
실제 구현의 예를 들자면, 만약 array.indexOf(item)으과 같이 등록 여부를 테스트하는 구문이 있다면, 아래와 같이 구현하면 된다.
var item:Object;
var dict:Dictionary = new Dictionary();
// 추가 시
array[index] = item;
dict[item] = index; // 또는 단순히 true나 null
// 확인 시
if (dict[item] == undefined)
{
// ...실행할 코드
}
단, 이때, Dictionary.hasOwnProperty(item) 과 같이 사용하면, 의도대로 동작하지 않으므로 주의하자.
적용 시 주의할 점
여기서 설명한 Dictionary를 이용한 방법은, 단지 퍼포먼스 튜닝법 중 하나일 뿐이며, 특수한 상황에만 적용된다. 특히 Dictonary의 생성 및 값 할당과 같은 trade-off가 발생하므로, 주의하여야 한다. 즉, 일반적인 경우에는 Array.indexOf(), Vector.indexOf()를 사용하는 것이 옳다. (개인적으로는, 성능 문제가 확실히 불거지기 전에 퍼포먼스 튜닝을 미리 진행하는 것은 바람직하지 못하다고 생각한다.2)
또한, 성능은 Player에 의존적이기 때문에, 플랫폼에 따라, 또는 플레이어 버전에 따라 언제든지 변경될 수 있으므로, (당연한 이야기이지만) 실제로 성능이 향상되었는지 꼭 직접 확인해야 한다.3
참고로 본인이 테스트하던 시뮬레이션의 경우, 해당 함수 호출 시 약 천만 번 정도 indexOf()가 호출되며, 실제로 이를 수행하는데 60초가 넘게 걸려, Script Timeout 에러가 발생하는 상황이었으므로, 퍼포먼스 튜닝이 필요했던 특수한 경우라고 할 수 있겠다.
결론
Array.indexOf()의 반복 호출로 인한 성능 문제는, 그다지 자주 부딪히는 문제는 아닐 것이다. 본인의 경우, 가장 마지막으로 접했던 것이 2년 전이었던 것으로 기억하는데, 그때에도 다른 부분에서 성능을 최적화함으로써 큰 지장 없이 넘어갈 수 있었다.
하지만, 아는 것과 모르는 것은 큰 차이가 있고, 또한 이는 Dictionary의 적절한 사용법 중 하나이므로4, 가치있는 정보라 판단하여 포스팅한다.
Reference
See Also
마치며 덧붙임
글을 마무리하던 중, 맹기완님의 글5에 같은 내용이 담겨있음을 확인하고, See Also에 추가하였다. Dictionary 뿐 아니라, ActionScript에서 제공하는 여러가지 참조 방법에 대해 자세히 다루고 있으므로, 읽어보는 것을 권한다.
또한 김학영님의 글6에서는 Indexed Array와 Associative Array의 개념을 잘 설명하고 있어, 언제 Array를 사용하고, 또 언제 Dictionary를 사용해야 하는지를 쉽게 이해할 수 있다.
'Adobe Flash Platform > Flex' 카테고리의 다른 글
| setActualSize()와 move() (9) | 2009/12/08 |
|---|---|
| Mustella와 Test 생성기 (8) | 2009/12/08 |
| Array.indexOf()가 괴롭힐 때 (0) | 2009/11/28 |
| 성능을 논하기 전에 (0) | 2009/11/28 |
| Function.apply()를 이용한 퍼포먼스 튜닝 (3) | 2009/11/27 |
| 커스텀 메타데이터 태그 (22) | 2009/11/26 |




댓글을 달아 주세요