CHAPTER 6. 행렬과 벡터 연산 6.3 메모리 단편화 파이썬은 벡터 연산을 기본으로 제공하지 않는다. 리스트로 확산(diffusion) 등을 계산할 때 문제가 있다. 파이썬의 리스트는 실제로 데이터를 가리키는 포인터를 저장하며, 파이썬 바이트코드는 벡터 연산을 위해 최적화되지 않았다. 따라서 for 루프는 연산을 언제 벡터화해서 수행해야 이루올지 예측할 수 없다. 파이썬 리스트가 실제 데이터가 아닌 포인터를 저장한다는 얘기는 리스트가 실제 데이터 대신 각 데이터가 저장된 위치를 담는다는 의미다. 이렇게 하면 데이터 종류에 상관없이 저장할 수 있으므로 대부분의 상황에선 좋은 선택이다. 하지만 벡터나 행렬 연산에서 이는 커다란 성능 하락의 원인이 된다. 성능이 하락하는 이유는 grid 행렬에서 항목 하..
CHAPTER 5. 이터레이터와 제네레이터 def range(start, stop, step=1): numbers = [] while start < stop: numbers.append(start) start ++ step return numbers def xrange(start, stop, step=1): while start < stop: yield start start += step for i in range(1, 10000): pass for i in range(1, 10000): pass 코드가 yield를 실행하는 순간 이 함수는 그 값을 방출하고, 다른 값 요청이 들어오면 이전 상태를 유지한 채로 실행을 재개하여 새로운 값을 방출한다. 함수가 끝나면 StopIteration 예외를 발생시켜 ..
CHAPTER 4. 사전과 셋 4.1.3 크기 변경 해시 테이블에 항목이 추가됨에 따라 해시 테이블의 크기도 그에 맞춰 변경되어야 한다. 테이블의 2/3 이하만 채워진다면 충돌 횟수와 공간 활용 측면 모두 적절하다고 볼 수 있다. 따라서 해시 테이블이 임계 크기에 다다를 때까지 계속 사용하면 된다. 해시 테이블은 데이터가 삽입 될 때에만 크기 변경이 일어난다. 4.1.4 해시 함수와 엔트로피 파이썬의 객체는 이미 __hash__ 와 __cmp__ 함수를 구현하고 있으므로 일반적으로 해시가 가능하다. 튜플과 문자열은 그 내용을 기반으로 해시값을 구한다. 반면 리스트는 그 값이 변경될 수 있으므로 해시를 지원하지 않는다. 사용자 정의 클래스도 기본으로 해시 함수와 비교 함수를 가지고 있다. 기본 __hash..
CHAPTER 3. 리스트와 튜플 3.1. 더 효율적인 탐색 파이썬 리스트는 정렬 알고리즘을 내장하고 있으며 팀(Tim) 정렬을 사용한다. 팀 정렬은 최적의 경우 O(n), 최악의 경우 O(nlogn)의 시간 복잡도를 가진다. 팀 정렬은 다양한 정렬 알고리즘을 활용하여 주어진 데이터에 어떤 알고리즘을 적용하는 것이 최선인지를 추측하는 휴리스틱을 사용한다(더 자세히 말하자면, 삽입 정렬과 병합 정렬 알고리즘을 조합해서 사용한다). 리스트를 정렬하고 나면 평균 O(log n)의 복잡도를 가지는 이진 탐색을 사용해서 항목을 찾는다. 이진 탐색은 리스트의 가운데 값과 찾고자 하는 값을 비교한다. 가운데 값이 찾고자 하는 값보다 작다면 찾으려는 값은 리스트의 오른쪽에 있을 것이다. 이런 식으로 값을 찾을 떄까지 ..
CHAPTER 2. 프로파일링으로 병목 지점 찾기 프로파일링을 해보면 병목 지점을 찾을 수 있기 때문에 최소한의 노력으로 성능을 최대한 끌어 올릴 수 있다. 큰 수고를 들이지 않고 속도를 크게 향상시키고 자원을 적게 사용하면서, 실용적인 측면에서 코드가 충분히 빠르고 유연한 것을 목표로 삼는다. 프로파일링을 통해 최소한의 노력으로 실용적인 결정을 내릴 수 있다. CPU뿐만 아니라 측정 가능한 자원은 모두 프로파일링을 할 수 있다. 이 장에서는 CPU 시간과 메모리 사용량에 대해서 살펴볼 것이다. 네트워크 대역폭과 디스크I/O 측정에서도 비슷한 기법을 적용할 수 있다. 2.1. 효과적으로 프로파일링 하기 프로파일링의 첫 번째 목표는 시스템의 어느 부분이 느린지, 혹은 어디서 RAM을 많이 쓰고 있는지, 디..