Machine learning이 대부분 python기반이다 보니 python을 더 정진하면 좋겠다는 생각에 시작합니다. 가시죠!
List와 Tuple은 배열이라는 자료구조 특성을 가집니다. 아래 그림은 배열이 메모리에 할당되는 방식입니다. 배열이 연속적인 메모리에 정렬되있음을 알 수 있다.
배열이란? 정해진 고유의 순서에 따라 데이터를 나열한것을 말합니다. 순서가 있기 때문에 배열 내 특정 위치의 데이터를 O(1) 시간 복잡도로 접근 가능합니다.
그래서 시작주소를 알고 있고 순서에 따라 나열되어있기 때문에 특정 위치의 데이터에 바로 접근가능합니다. 예를 들어 3번째 위치의 데이터에 접근하고 싶으면 0x06에서 2칸떨어진 0x08위치의 값을 읽으면 됩니다.
그렇다면 List와 Tuple의 차이는 멀까?
- List: 저장하는 데이터나 배열 크기를 변경할 수 있는 동적 배열
- Tuple: 내용이 고정된 변경 불가능한 정적 배열
1. List
List는 동적 배열임을 기억하자! 그래서 저장 용량을 늘리거나 줄일 수도 있다. 추가적으로 수정이 가능하다는 것이 특징입니다.
수시로 데이터가 변경되거나 추가되고 삭제되는 내용을 나타내려면 리스트를 사용해야 합니다.
a = [1, 'a', 2, 'b']
a.append(3)
위의 코드에서 보이듯이 list는 대괄호([ ])로 선언 가능하며 데이터 타입을 섞어서 사용할 수 있고 (뒤에서 말하겠지만 물론 tuple도 가능하다) append
함수로 데이터를 추가 가능합니다. 이는 동적 배열이 배열의 크기를 변경하는 resize 연산을 지원하기 때문입니다.
특징점은 배열의 크기가 \(N\)일때 1개의 요소가 더 추가될 때 배열의 크기가 \(N+1\)이 되는 것이 아니라 나중을 위한 여유분으로 \(N\)보다 큰 \(M\)만큼의 메모리를 할당한다. 이는 데이터가 추가될 때마다 메모리 할당과 복사 요청을 줄이기 위함이에요. (복사 비용이 큽니다!)
다음은 파이썬 3.7기준으로 리스트 크기 할당 방정식이에요. 해석하자면 \(N\)이 현재 리스트 안의 데이터의 개수(크기)이고 \(M\)은 해당 리스트의 할당된 메모리 크기이다.
M = (N>>3) + (3 if N < 9 else 6)
# N | 0 | 1-4 | 5-8 | 17-25 | 26-35| ... | 991-1120|
# M | 0 | 4 | 8 | 25 | 35 | ... | 1120 |
예를 들어 현재 리스트 크기가 4이고 하나의 데이터를 더 추가하게 되면 8개의 메모리 크기를 가진 새로운 리스트를 생성하게 됩니다! (만약 우리가 데이터를 991개만 사용하는 리스트를 반복적으로 새로운 변수에 할당하는 프로그램이 있다면 사실상 각 변수는 메모리를 1120개 데이터를 사용하는 것과 같으므로 리스트를 사용할때는 조심해야하는 부분이다. 손해다..ㅠ)
2. Tuple
Tuple은 정적 배열이며 내용을 바꾸거나 크기를 변경하지 못합니다. Tuple은 소괄호('( )')로 선언가능합니다.
b = (1, 'a', 2, 'b')
b[1] = 'c' # error
위와 같이 Tuple이 크기를 변경할 순 없어도 두 개의 튜플을 새로운 튜플로 합칠 수 있습니다. 이는 정확히 합친 만큼의 메모리를 할당하는 것이기 때문에 List와 달리 여유공간 메모리를 주지 않습니다.
b1 = (1,2,3,4)
b2 = (5,6,7,8)
b3 = b1 + b2 # b3 is (1,2,3,4,5,6,7,8)
그래서 Tuple이 정적인 데이터를 쓸 때(e.g. 주민등록번호, 여권번호) 더 가볍고 효과적입니다.
그리고 정적이기 때문에 파이썬이 내부적으로 수행하는 리소스 캐싱이 가능하다는 것이 특징입니다. 파이썬은 Garbage Collection(GC)을 통해 더 이상 사용되지 않는 변수에 할당된 메모리를 반환해 해제합니다. 하지만 크기가 20이하인 Tuple은 크기별로 최대 2만개(e.g. 크기가 1인 tuple 2만개, 2인 tuple 2만개, ....)까지 즉시 해제하지 않고 나중을 위해 저장해둡니다. 그래서 나중에 다시 필요해지면 OS에서 메모리를 새로 할당받지 않고 기존에 할당해둔 메모리를 재사용합니다.
아래는 캐싱의 차이를 보여주기 위해 list와 tuple 차이 예시입니다.
timeit모듈은 작은 python code의 execution time을 측정하는 것입니다. 위 그림으로부터 List와 Tuple의 할당을 100,000번 실행한 결과를 볼 수 있습니다. List는 100,000번 운영체제에서 새롭게 메모리를 할당받아 실행하고 해제하는 것을 반복하지만 Tuple은 한번 메모리를 할당하고 해제하지 않기 때문에 바로 캐싱을 통해 메모리를 재사용합니다. 그래서 속도 차이를 보면 Tuple이 List보다 약 6배 빠른 것을 볼 수 있습니다.
'Computer Science' 카테고리의 다른 글
VMAF Optimization과 VMAF NEG 이해 (0) | 2024.02.01 |
---|---|
Per-shot Encoding 설명 (0) | 2023.02.06 |
Per-title Encoding 설명 (0) | 2022.12.03 |
VMAF score 란? (0) | 2022.07.09 |
Python (2) Dict와 Set 차이 (0) | 2022.05.22 |