[Python] 파이썬 Thread and Pool Manager GitHub 주소 https://github.com/sanggi-wjg/py-thread-manager 코드 import os from pool_manager import PoolManager def calculate(x): print(f"[{os.getpid()}] func: {x}\t\t", r := x ** 5 ** 2, flush=True) return r manager = PoolManager() manager.add_task(calculate, [i for i in range(2, 22)]) manager.run_map() manager.add_task(calculate, [i for i in range(2, 22)]) mana..
Python Linter Linter 종류와 개요 구 분 flake8 pylint bandit 종 류 linter linter security linter Star 2.3K 4.2K 4.5K 특 징 코드 스타일, 오류 복잡성 검사 코드 스타일, code smell, 오류 등을 검사 unsafe coding 검사 장 점 간단함, 많은 플러그인이 있음 세팅 비용이 flake8 비해 높음 단 점 많은 플러그인을 있음 린트 통과가 flake8 비해 까다로움 다른 개발자들은 어떻게 사용할까 (from Reddit, StackShare) flake8 + pylint 사용하는 경우 flake8 + pylint + bandit 사용하는 경우 (flake8 or pylint) + bandit 사용하는 경우 전자들과 추가..
[Python] lru_cache 0. 개요 LRU(Last Recently Used) 는 운영체제 OS에서 메모리 관리에서 Page 교체에서 사용되는 알고리즘 중 하나로 가장 오랫동안 사용하지 않은 것을 교체하는 방식입니다 알고리즘 설명 : https://www.geeksforgeeks.org/lru-cache-implementation/ Python에서는 @lru_cache 로 데코레이터로 기능을 제공해주고 있습니다. 1. 기대 효과 Memorization 으로 추가 계산 감소 CPU-Bound 감소 2. Sample Code lru_cache 데코레이터는 실행 함수에 3가지 함수를 추가합니다. 사용 방법은 @lru_cache(maxsize=128, typed=False) maxsize : lru_c..
[Python] Object class __slots__를 이용한 성능 개선 0. 개요 Python에서는 Object attribute에 대해서 메모리는 더 적게 사용, 접근 속도는 더 빠르게 하는 방법이 있습니다. 바로, __slots__ 를 사용하는 방법 입니다. 기본적으로 Python은 객체 인스턴스 속성을 Dict를 사용 생성하며 Dict 형은 메모리를 추가적으로 필요로 합니다. slots 을 사용 하는 경우 class는 __dict__, __weakref__ 생성을 하지 않습니다. It restricts the valid set of attribute names on an object to exactly those names listed. Since the attributes are now fi..
[Python] Concurrency Thread Decorator Thread Decorator 정말로 간단한 함수들을 Thread를 사용하기 위해 계속 같은 코드를 구현하는 것을 피곤하다. 다행히도 Python은 Decorator 기능이 있다. Decorator기능을 활용해서 간단한 비동기 I/O 함수들은 Thread로 동작하도록 하자. HTTP Reqeust는 Thread 보다는 async await를 활용한 Coroutine으로 작성하고 안에는 꼭 비동기를 지원하는 패키지를 사용하자. def using_thread(func: Callable): def decorator(*args): th = Thread(target=func, args=(*args,)) th.start() return th ret..
PDF 파일 생성 PDF 파일 생성은 비동기 I/O 작업이다. 평벙하고 쉽게 누구나처럼 그냥 함수 혹은 클래스 작성해서 반복문으로 구현할 수도 있지만, 정말로 업무가 급하고 그런게 아니라고 한다면, 빠르게 동작을 할 수 있도록 하자. Sample Data와 Package import random import uuid from threading import Thread from faker import Faker from fpdf import FPDF fake = Faker() class Person: # slots는 Class attr에 빠른 접근 및 제어, 적은 메모리 사용에 이점이 있다. __slots__ = ['name', 'age', 'location'] def __init__(self, name:..
어느 상황에 어떤 Concurrency API를 사용하는게 좋을까 우리는 평소 개발 업무를 하면서 최대한 Response latency, Memory Usage 등을 줄이기 위해 노력을 한다. 예를 들어, ORM을 사용하는 경우 N+1 이나 1+N+a 등 Query Fetch를 줄이거나 또는, Algorithm을 이용해 시간복잡도를 최대한 적게 할려고 하는 등 말이다. 그럼 Python에서 비동기 소스를 개발할 때는 어떠한 경우에 어떻게 해야 좋은지 알아보자. 우선 Python이 제공하는 concurrency API는 다음과 같다. Coroutine: asyncio module Thread: threading module Process: multiprocessing module 이 3가지의 module ..
TTS with FastAPI FastAPI에서 TTS 구현 app/api/tts.py DB exist 체크로 생성되지 않았던 tts파일만 생성 하도록 되어있는데 사용량이 많다고 한다면 Insert가 많아지니 당연히 DB에 부담이 갈수 있다. 따라서, Redis Set로 저장하고 체크하는 것이 더 효율적으로 보인다. @router.get("/tts/{text}", response_class = FileResponse) async def get_tts_mp3(text: str, db: Session = Depends(get_db)): if not tts_record_repo.is_exist_tts_record(db, text): tts_record_repo.create_tts_record(db, text)..
Python TTS 방법 TTS(Text to Speech) 기술은 유튜브, 트위치 등 인터넷 방송 뿐만 아니라 네이버, 구글 번역 사이트 등 발음 기능 등으로 웹 서비스로도 많이 사용 되는데 TTS는 어떻게 작동 되는지 한번 알아보자. 1. TTS 개요 TTS는 머신 러닝 등을 이용하여 텍스트에서 인간의 발언으로 구현해주는 것이다. TTS를 이용하여 메뉴얼 녹음이라든지 회사 비지니스 관점에서 시간이나 돈 등을 절약할 수 있는데 https://github.com/pndurette/gTTS TTS 구현 방법 연결 (Concatenative) 방식 녹음된 오디오의 조각을 이어 붙이는 방식으로 매우 고품질을 제공하지만 머신 러닝을 위해서 많은 데이터가 필요하다. 매개변수 (Parametric) 방식 주어진 텍..
Python Speech Recognition 방법 파이썬에서 음성 인식 하는 방법. 음성 인식을 기술을 활요하여 이미 아마존 알렉사, 카카오 미니 등 다양한 제품들이 현재 집에서 서비스를 하고 있다. 그럼 음성인식이란 어떤것이고 어떻게 작동을하고 간단한 개요를 확인하고 파이썬에서 음성인식과 TTS를 활용하여 간단한 데모를 구현 해보자 1. 음성인식 개요 음성인식은 1950년대 Bell Labs에서 연구의 기초를 둔다. 처음에는 한명의 말과 수십개 정도의 단어 정도에서 였지만 현재는 수많은 사람의 말과 수많은 언어의 단어를 인식 한다. 작동 방법 → Physical Sound with Microphone → Electrical Signal → Digital Data with Analog-to-Digita..
Python Thread와 Async를 이용한 비동기 방법 이후 Client에서 Request 보낼 Server의 소스는 다음과 같다. @router.get("/second") async def second(): return { "second": random.randint(1, 100), } 그리고 일반 함수를 생성해서 Server로 Request 했을 때, 약 20초 걸린다. import datetime import requests def second_request(): resp = requests.get("http://localhost:8090/second") start = datetime.datetime.now() for _ in range(0, 10): second_request() print(d..
Validate Class Attributes in Python Python에서 DTO, Data Class로 사용하는 Class를 Validation 하는 여러 방법을 알아보자 1. Validation method 사용 간단한 방법으로 __init__ 메소드에서 validate 하는 방법이다. 만약 유효하지 않다면 ValueError Exception 처리 될것이다. class Person(object): def __init__(self, id: int, name: str, age: int): self.id = id self.name = self._clean_name(name) self.age = self._clean_age(age) def _clean_name(self, name: str): if n..
Python With Go Python 은 쉽고, 깔금하고, 독립적이며, 짧은 시간안에 개발을 할 수 있으며, 수많은 라이브러리들을 사용 할 수 있다는 점에서 좋은 언어 이다. 다만, 파이썬의 장점의 모든 것들은 속도 라는 대가를 가진다. (numpy 같은 c 라이브러리 제외 하고는...) pypy 나 pyc 등에 속도 향상을 대체도 있지만 실제 사용해보면 현실은 녹록치 않다. Go to Python Go 에서는 Go 를 C에 연결을 혹은 C를 Go에 연결을 도와주는 라이브러리를 제공한다. https://golang.org/cmd/cgo/ Python 에서는 C 모듈을 가져와서 사용 할 수있는 기능이 있기 때문에 Go도 마찬가지로 사용이 가능하다. Go .so 파일 만들기 import "C" 와 사용 할..
파이썬 Magic Method https://docs.python.org/ko/3.7/reference/datamodel.html#special-method-names new 인스턴스 생성시 호출되며 Static method 이다. 일반적인 구현은 super().new(cls) 로 인스턴스 생성후 Return 전에 필요한 작업을 함 만약 인스턴스를 Return 하지 않는다면 init 은 호출되지 않는다. class Sample(object): def __new__(cls, *args, **kwargs): print('new', args, kwargs) this = super().__new__(cls) cls.args = args cls.kwargs = kwargs return this def __init..
multiprocessing 파이썬은 기본적으로 여러 CPU를 사용하지 않는다. 단일 코어 시대에 설계 되었고 병렬 처리를 효율적으로 실행하기가 어렵기도 하다. 로직을 병렬화하면 N배의 속도를 기대하지만 실제로는 프로세스간 통신 비용이 발생 등 N배 만큼에 성능 향상이 이루어지지는 않는다. 또는 어떻게 설계하냐에 따라서 오히려 더 느려지는 경우도 있기 때문에 설계를 잘 해야한다. multiprocessing 모듈은 프로세스와 스레드 기반의 병렬 처리를 사용해 작업 대기열을 분산시키고 프로세스 간에 데이터를 공유할 수 있도록 한다. 작업을 병렬화 하려면 순차적으로 작성하는 방식과는 달리 다른 관점으로 작성을 해야하며 일반적으로 디버깅이 어렵다. 따라서 성능도 중요하지만 유지보수 측면에서 단순하게 작성을 해..
비동기 I/O 개발 업무를 하면서 실제 코드 자체보다는 코드에 필요한 데이터를 얻어오는 작업이 병목이 생기는 것을 많이 겪었을 것이다. 이런경우 프로그램 I/O 위주라 하고 I/O 효율이 속도를 제한 한다는 것을 의미한다. I/O는 프로그램 흐름에 큰 영향을 미친다. 파일이나 네트워크 소켓 연결을 통해 데이터를 읽을 때까지 실행을 멈추고 커널에 연산을 요청한 후 끝날때 까지 기다려야 하기 때문이다. 비동기 I/O를 활용하면 I/O 연산을 기다리는 동안 다른 연산을 수행하여 유휴 시간을 활용할 수 있다. 작업1,2,3 을 순차적으로 실행한다면 지연을 세번 감수해야 하지만 세 작업을 동시에 실행한다면 시간을 감소할 수 있을 것이다. 파이썬에서는 제너레이터 기반의 Coroutine과 async 함수로 Nati..
사전(dict)과 셋(set) dict와 set은 미리 정해진 순서로 정렬 되지 않는다. dict와 set의 차이점은 set은 key만 가지고 있다는 것이다. 리스트와 튜플은 경우에 따라 검색을 O(logN) 시간 복잡도로 구현할 수 있다. 반면, dict와 set은 O(1)이다. dict와 set은 보통 많은 메모리를 사용한다. 또 해시 함수에 의존 함으로 해시 함수가 느리다면 연산속도도 느릴 것이다. 리스트와 사전 검색 성능 차이 리스트 or 튜플로 구현시 O(N) dict로 구현시 O(1) phonebook_list = [ ("홍길동", "010-1111-1111"), ("김철수", "010-1111-1234"), ("국영수", "010-1234-1234"), ] def find_phonebook_..
튜플 튜플은 한번 생성되면 내용이나 크기를 변경할 수 없지만 두 튜플을 합칠 수는 있다. >>> t1 = (1,2,3) >>> t2 = (4,5,6) >>> t1 + t2 # (1,2,3,4,5,6) 튜플은 합치면 항상 메모리에 새로운 튜플을 새로 할당 한다. 또 튜플은 여유공간을 할당하지 않기 때문에 자원을 더 적게 사용한다. l = [i for i in range(100000)] t = tuple(l) print('list', sys.getsizeof(l)) print('tuple', sys.getsizeof(t)) list 824464 tuple 800048이 때문에 정적인 데이터를 다룰때는 리스트보다는 튜플이 좋다. 또한 튜플은 정적이기에 리소스 캐싱을 하는데 크기가 ..
리스트 리스트는 동적 배열로 크기를 자유자재로 조절할 수 있는데 이러한 변경 가능한 특성 때문에 리스트는 메모리와 추가 연산을 필요로 한다. 리스트에 object 추가 시 기존에 object들과 추가되는 object를 새로운 리스트를 추가하여 생성한다. 새로 추가된 리스트의 크기는 기존 N개와 추가되는 1개 더하여 N+1이 아니라 M개 (M > N+1) 의 크기를 가진다. 크기에 여유를 두는 이유는 메모리 할당과 복사 요청 횟수를 줄이기 위하여다. 리스트의 크기 1을 할당한 이후 크기는 동일하다가 5를 할당하니 크기가 커진다. 이는 새로 리스트를 생성한 것. a = [] print('0', sys.getsizeof(a)) a.append(1) print('1', sys.getsizeof(a)) a.app..