Python에서 list에 어떻게 메모리를 할당하는가에 대한 나름의 생각을 정리해본다. 확실한 사실을 향해 가도록 공식 문서와 자료들을 더 찾아보고 공부할 것이다.
C, C++에서(아마 Java도) 배열을 할당하고 배열 원소들의 주소를 확인해보면 다음과 같다.
1 |
|
배열의 첫 주소에서 배열의 자료형인 int의 크기 4Byte만큼 더해지면서 차곡차곡 쌓이게 되고, 이를 보면 다음과 같은 공식을 어렵지 않게 생각할 수 있다.
인덱스 i번째 원소의 주소 = 배열 시작 주소 + (i * 자료형 크기)
이처럼 미리 자료형을 특정한다면 배열의 find by index의 원리는 크게 어렵지 않다.
그런데 문제는 Python이다. 이론적으로는 list에 모든 형태의 객체가 들어갈 수 있다.
1 |
|
물론 list를 이렇게 사용하는 사람은 거의 없겠지만, 이런 배열구조에서 어떻게 find by index가 작동하는지 꽤나 궁금하다. 직접 각 원소의 id를 찍어보자.
1 |
|
배열 원소들간의 주소가 아예 연관성이 없어보이지는 않지만, 그렇다고 해서 이걸 가지고 메모리 할당 위치를 특정하는 규칙이 있다고 보기에는 무리가 있다.
2가지 경우의 수를 생각해보았다.
1. list에 들어오는 값에 따른 메모리 할당
[Python] Python의 자료형과 크기에서도 말했지만, Python은 C로 작성된 object 관련 코드를 거치면서 자료형이 정해진다.
1 |
|
이 과정에서 자료형 크기별로 메모리 크기를 알 수 있고, 내부 최적화를 통해 할당 간격 / 위치를 정하는게 아닐까?한 것이 첫번째 생각이다. 사실 위에서 확인한 Python list의 주소를 봤을 때는 이 가설은 믿기 어렵다. 증감도 제멋대로이고 그 간격도 일정하지 않기 때문에 최적화에 따른 규칙이 있다고 보기는 어렵기 때문이다.
하지만 이런 경우에는 조금 다르다.
1 |
|
list 안의 원소들이 모두 같은 자료형을 가지고 있다면 c와 비슷하게 일정 크기만큼 주소의 크기가 증가하는 것을 볼 수 있다. 이 경우에는 확실히 최적화를 통해 효율적인 메모리 관리(c처럼)를 하고 있다고 볼 수 있다.
2. 주소로 이루어진 별도 list의 존재
list 안에서 자료형 크기만큼 메모리를 먹을 수 없는 Python 언어의 특성상, list와는 별도로 주소를 따로 저장하는 list / linkedList가 있을거라 생각한다. 이를 기반으로 list에 값이 할당될때마다 메모리 어딘가에 값을 배치하고, find by index시에는 별도의 주소 list를 이용해 값을 출력해준다고 보는 것이 내 상식 선에서는 합리적인 추론이다. 주소의 크기는 같은 OS 안에서 모두 같기 때문에 관리가 가능할거라 본다.
찾아보니 이런 방식이 맞는 듯하다.
결론
위 2가지가 적절하게 이용된다고 보는 것이 맞는듯 하다. 새삼 쓰기 편하고 배우기 쉬운 Python
이라는 타이틀 뒤에 얼마나 많은 엔지니어들의 노력과 고민이 있었을지 생각해보게 된다.