자바이야기를 해볼건데, 이건 모든 VM(Virtual Machine)관련 언어들도 관련있는 이야기다. 결국 스크립트 언어들도 관련이 있다는 이야기.
상식적으로 생각했을때, Stack에서 사용하는 자료구조들이 더 빠를수 밖에 없는데 왜냐면 CPU Register가 가리키는 Pointer에 의하여 관리가 되기 때문. 이야기를 이해하려면 컴퓨터 구조를 알아야함.
간단히 설명하면 Native Execution 하는 프로그램의 경우 SP(Stack Pointer) + 숫자. 로 변수에 접근함. 그런데 Heap만 되어도 포인터로 관리하기 떄문에 메모리에서 관리하는 Pointer를 Cpu에 넣고 그 Pointer 주소를 가지고 다시 Heap에 접근함. 한단계 더 가니까 느릴수 밖에?... 그런데 이 한단계가 Cpu Pipeline 거치거나 하면 거의 오버헤드가 없는거(메모리 로드정도의 오버헤드)라고 봐도 되는지라 별 의미 없음.(그래도 한단계 더 거치는건 거치는거니까)
그런데 여기서 왜 이 이야길 하냐면 모든 객체 인스턴스는 heap에 생성됨. 그러면 결국 stack에 접근하는거보다 heap에 접근하는게 더 비싸니까 객체의 data에 접근하는건 stack의 data에 접근하는거보다 느리니까 Stack을 쓰는 Primitive Type이 더 빠를수 밖에 없음. 여기서 JVM을 사용하는데 결국 stack을 사용해도 JVM 위에서 사용하는거 아니냐는 물음이 들면 컴퓨터 구조와 OS 제대로 수강하신거임...(결국 JVM 프로세스 안에서 도는거니까) 자바 프로그램의 stack은 JVM 내부의 stack에서 돌기때문에 Native Execution 보다는 좀더 느리나(인터프리팅 과정때문에) 크게 오버헤드가 없다고 보면 됨.
그리고 heap primitive type을 생성하는것과 객체 인스턴스를 생성하는것은 오버헤드 차이가 크다. primitive type은 메모리를 사이즈 계산해서 그냥 할당하면 되는데 객체 생성은 그에따른 함수링크와 같은 초기화 과정이 있기 때문. 그럼 무조건 primitive Type이 빠른거 아닌가? 라는 생각을 할 수도 있다.
그런데 size가 fixed면 primitive type은 stack에 할당해도 상관 없는 이야기인데(왜냐면 기계어는 컴파일타임에 stack의 어느부분에 접근할지 결정하니까) 그때그때 다른 프로그램이라면 컴파일타임에 정할수가 없다. 그래서 heap에 해야한다는거.
여기까지 이야기를 해도 그럼 무조건 primitive가 우위아닌가? 할텐데... 문제는 이게 VM이라는거. GC(Garbage Collection)를 빼고 이야기 할 수가 없다. 여기서 한가지 더 알아야할것이 등장하는데 메모리 단편화다. 우리가 생각할때는 메모리가 아래와같이 있음면 순서대로 할당이 될거같은데
[-------------------------------------------------------------------] 이게
[AAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBB] 요렇게
그런데 이렇지 않다는거
[---------AAAAAAAAAAAAAAA----------------------------------] 요래 중간에 있어서
[AAAAAAAAAAAAAAA-------------------------------------------] 요렇게 옮긴다음에 넣어야 할 수도 있다는거다......
요게 간단한 메모리 단편화의 오버헤드인데 이렇게 할당이 되면 메모리 할당 해제에 많은 코스트가 들게 됨. 왜 저렇게 되냐면 엄청나게 많이 할당했다가 해제를 하면 저렇게 되는경우가 있다고 알면 되겠다. GC 전략에 따라서 다르겠지만.... 단편화되어 관리되는거보다 linked list로 관리하는게 더 비용이 싸다. 왜냐면 안옮겨도 되니까....
그럼 결론은 아래와같은데
1. arr[FIXED_SIZE] vs ArrayList(FIXED_SIZE) => arr[FIXED_SIZE] 이 빠를수 밖에 없음.
2. new arr[DYNAMIC_SIZE] vs ArrayList[DYNAMIC_SIZE] => 여러번 돌릴경우 ArrayList가 빠를 확률이 매우 높음.
3. primitive Array Fixed Size > arraylist Fixed Size > arraylist extensible size 으로 성능이 좋음.
이것저것 신경쓰기 싫으면 ArrayList 쓰면 중간은 간다... 라고 생각하면 되겠다.
'컴퓨터공학' 카테고리의 다른 글
[소프트웨어공학] 수평조직, 방어적태도, 공격적태도, 오버커뮤니케이션 (0) | 2022.11.21 |
---|---|
[가상화] KVM 기본 구조 (0) | 2019.04.29 |
[개발이야기] CD(Continuous Development) (0) | 2019.04.26 |
[성능튜닝] 자바스크립트 페이지로딩 (0) | 2019.04.21 |
[ANDROID] Funf wifi-scanner 구조 (0) | 2019.04.09 |