본문 바로가기

반응형

Computer/Python

(57)
Argparse nargs, const, default 인자 사용법 파이썬 파일 실행 시 원하는 인자를 커맨드라인 상에서 전달하기 위해 argparse 패키지를 많이 사용할 겁니다. 실제로 파이썬에서 처음 접하게 되는 내장 라이브러리 중 하나입니다만 argument를 추가할 때 사용하는 함수의 (add_argument 함수) type, default 인자 이외의 생소한 인자를 만나게 되면 항상 사용법을 검색하게 되는데, 저 같은 경우는 nargs/const/default 인자입니다. nargs 인자 nargs 인자는 Number of Arguments 의미를 가지며 말 그대로 해당 argument에 대해 몇 개의 value를 넣을 것인지를 정합니다. 구체적인 숫자를 넣어도 되고 쉘 스크립트에서 사용되는 wildcard 캐릭터도 사용법이 미리 정의되어 있습니다. CLI 상..
파이썬의 추상 클래스 (Abstract Class) 코드가 고도화되고 모듈화 되면서 클래스 상속을 이용하는 경우가 많습니다. 특히, 여러 메서드의 이름은 공유하지만 각 클래스 별로 기능을 다르게 구현해야 하는 경우도 많죠. 따라서 관련된 함수, 메서드를 하나의 단위로 묶어 응집성을 강화하고자 하는 방편으로 파이썬에서는 추상 클래스라는 기능을 제공합니다. "추상"이라는 말 그대로 디테일한 기능이 구현되어 있지 않지만 이 클래스를 상속해서 만드는 클래스들에 필수적으로 정의해야 할 변수, 메서드를 선언만 해놓은 것이죠. 파이썬에서는 abc (abstract base class) 라이브러리를 제공합니다. 먼저 모델의 이름과 사이즈를 선언해야 하는 추상 클래스를 선언하겠습니다. from abc import ABCMeta, abstractmethod class Mo..
Numba (2) - 타입 컨테이너, 루프 퓨전 Numba (1) Numba 타입 컨테이너 Numba에서 가장 중요한 권장 사항은 최적의 컴파일을 제공하는 "nopython" 모드를 사용하는 것일 겁니다. (오브젝트 모드 (object mode)는 최소한의 최적화만 진행하게 됩니다) 이는 @jit 데코레이터에 "nopython=True" 옵션을 주거나 @njit 데코레이터를 사용하면 되는데요, 하지만 지난 포스트에서 살펴봤듯이 이 모드는 제한이 많아 컴파일이 성공하려면 Numba가 작상한 함수 내의 모든 변수 타입을 추론할 수 있어야 합니다. Numba는 튜플, 문자열, 이넘, 정수, 실수 등의 간단한 스칼라 타입과 넘파이 배열 데이터 타입을 지원하지만 대표적으로 리스트, 딕셔너리 아규먼트에 대해서는 동작하지 않습니다. 이는 파이썬 리스트나 딕셔너리는..
파이썬 코드 C언어로 컴파일하기 (3) - 사이썬과 넘파이 파이썬 코드 C언어로 컴파일하기 (1) 파이썬 코드 C언어로 컴파일하기 (2) 이 포스트에서 살펴봤듯이 파이선의 리스트 객체는 실제 데이터가 아니라 데이터가 저장된 주소를 담고 있기에 리스트 객체가 가리키는 객체는 메모리의 어디든 존재할 수 있습니다. 따라서 역참조에 따른 부가비용이 발생합니다. 하지만 배열 객체는 기본 타입을 연속적인 RAM 블록에 저장하므로 주소 계산이 빠르고 파이썬에서는 array 모듈로 기본 타입에 대한 1차원 저장소를 제공합니다. 넘파이의 array 모듈을 사용하면 다차원 배열을 지원하죠. 따라서 파이썬에서 다음 주소를 요청하지 않고 연속적인 메모리 공간에 놓인 배열 객체를 이용해 오프셋을 이용해 다음 메모리 주소를 직접 계산하도록 접근한다면 파이썬 가상 머신을 호출할 필요가 없..
파이썬 코드 C언어로 컴파일하기 (2) 파이썬 코드 C언어로 컴파일하기 (1) 지난 포스트에서 calculate_z 함수를 사이썬으로 빌드하여 속도 개선을 얻었지만 calculate_z 함수 내용을 아예 건드리지 않고 그대로 빌드했습니다. 그렇다면 무엇을 어떻게 변경하면 추가적인 속도 개선을 얻을 수 있을까요? C언어와 파이썬의 여러 차이점 중 하나는 C언어는 변수의 타입을 미리 지정하는 정적언어인데 반해 파이썬은 변수가 어떤 타입이라도 참조할 수 있고 코드 어디에서든 참조하는 객체의 타입을 변경할 수 있는 동적언어라는 점입니다. 따라서 순수 파이썬으로 작성된 코드는 동적언어라는 특징 때문에 가상 머신에서 다음 연산에 사용할 기본적인 데이터 타입을 알 수 없으므로 기계어 수준의 최적화를 수행하기 어렵습니다. 실행 속도 대신 개발 속도를 선택한..
파이썬 코드 C언어로 컴파일하기 (1) 코드를 빠르게 하는 가장 쉬운 방법은 처리해야할 작업의 양, 데이터를 간소화하고 프로파일링을 통해 병목이 발생하는 구문을 최적화하는 것입니다. 특히, C 언어를 이용한 더 낮은 수준 (low level)으로 코드를 기계어로 컴파일하면 간단하게 큰 속도 향상을 얻을 수 있습니다. 특히, 같은 연산을 무수히 반복하는 루프를 포함하는 수학적인 코드에서는 임시 객체를 사용할 확률이 높기에 컴파일을 통해 큰 이득을 얻을 수 있습니다. 다만, 정규 표현식, 문자열 연산, 데이터베이스 등의 외부 라이브러리를 호출하는 코드는 속도 개선을 기대하기 어렵고 numpy 또한 벡터 연산을 집중해서 호출하고 임시 객체를 많이 생성하지 않아 컴파일이 별로 도움이 되지는 않습니다. (이미 C기반으로 최적화가 되어있기도 하고요) L..
행렬과 벡터 연산 (6) - numexpr 모듈 이용하기 행렬과 벡터 연산 (1) - 확산 방정식 예제 행렬과 벡터 연산 (2) - 확산 방정식 순수 파이썬 구현 행렬과 벡터 연산 (3) - 파이썬 리스트와 numpy 연산 속도 차이 행렬과 벡터 연산 (4) - numpy 배열을 이용한 확산 방정식 행렬과 벡터 연산 (5) - numpy 배열 메모리 최적화 지난 포스트를 거치면서 1) 메모리의 지역성, CPU 벡터 연산 활용을 지원하는 numpy 배열을 이용하고 2) 제자리 연산, numpy 함수 개량 등을 통해 확산 방정식의 속도를 크게 개선했습니다. 제자리 연산을 통해 메모리 재활용을 할 수 있어 캐시 미스를 줄일 수 있었지만 제자리 연산은 한 번에 하나의 연산에만 적용할 수 있는 단점이 있습니다. 예를 들어 A*B+C를 계산한다고 했을 때, 먼저 A*B ..
행렬과 벡터 연산 (5) - numpy 배열 메모리 최적화 행렬과 벡터 연산 (1) - 확산 방정식 예제 행렬과 벡터 연산 (2) - 확산 방정식 순수 파이썬 구현 행렬과 벡터 연산 (3) - 파이썬 리스트와 numpy 연산 속도 차이 행렬과 벡터 연산 (4) - numpy 배열을 이용한 확산 방정식 그렇다면 numpy 배열로 메모리 할당 횟수 (캐시 미스)를 줄인 이후에 메모리 할당 부분은 어떻게 최적화할 수 있을까요? 필요한 데이터를 캐시에서 찾지 못하면 메모리 할당은 단순히 메모리를 찾아보는 대시니 필요한 크기만큼의 데이터를 운영체제에 요청하게 됩니다. 캐시를 채우는 과정은 하드웨어적으로 최적화된 것에 반해 운영체제에 무언가를 요청할 때 발생하는 오버헤드는 (특히 메모리 할당) 커널과 통신해야 하므로 매우 큽니다. 제자리 연산 (in-place operat..

반응형