[cpython] CPython 최적화: functools.reduce 대신 Union 직접 사용하기
PR 링크: python/cpython#155280 상태: Merged | 변경: +3 / -2
들어가며
Python의 typing 모듈에서 Union 타입을 다룰 때, 기존에는 여러 타입을 하나로 합치기 위해 functools.reduce(operator.or_, args) 방식을 사용해 왔습니다. 하지만 이 방식은 타입 개수가 늘어날수록 연산 비용이 기하급수적으로 증가하는 문제가 있었습니다. CPython의 이번 PR(gh-105499)은 Union 객체를 재구성할 때 functools.reduce를 제거하고, Union[args] 문법을 직접 사용하여 성능을 대폭 개선했습니다.
코드 분석
Lib/typing.py
핵심 변경 사항은 _eval_type 함수와 _strip_annotations 함수 내에서 functools.reduce를 제거하고 Union 인덱싱을 사용하는 것입니다.
Before:
if isinstance(t, Union):
return functools.reduce(operator.or_, ev_args)
After:
if isinstance(t, Union):
return Union[ev_args]
이 변경은 reduce를 통해 매번 | 연산자를 호출하며 새로운 Union 객체를 생성하는 오버헤드를 줄이고, Union 생성자가 내부적으로 최적화된 방식으로 인자들을 처리하게 함으로써 성능 이득을 얻습니다.
Lib/test/test_typing.py
변경 사항의 정확성을 검증하기 위해 테스트 코드에도 Union[args]를 사용하는 케이스가 추가되었습니다.
After:
self.assertEqual(expr1, reduce(operator.or_, args))
self.assertEqual(expr1, Union[args])
왜 이게 좋은가
성능 향상
벤치마크 결과에 따르면, 타입 멤버가 80개인 경우 reduce 방식 대비 약 35.66배의 속도 향상을 보였습니다. 타입 개수가 적을 때는 차이가 미미하지만, 복잡한 타입 힌트가 많은 대규모 코드베이스에서는 typing 모듈의 오버헤드를 획기적으로 줄일 수 있습니다.
교훈
- 내장 문법 활용: 특정 기능을 구현할 때 범용 라이브러리(
functools.reduce)를 사용하는 것보다, 언어 차원에서 제공하는 전용 문법(Union[...])을 사용하는 것이 훨씬 빠르고 효율적입니다. - 연산 복잡도:
reduce는 매 단계마다 중간 객체를 생성할 가능성이 높지만,Union[args]는 인자들을 한 번에 처리하여 객체 생성 비용을 최소화합니다.
리뷰어 피드백
리뷰 과정에서 Union[...]의 잠재적 deprecation 논의가 있었으나, Union의 가변 인자 지원은 계속 유지될 것이라는 점이 확인되었습니다. 또한, | 연산자와 달리 Union[...]은 문자열 타입(ForwardRef) 처리 등에서 더 안전하고 일관된 동작을 보인다는 점이 장점으로 언급되었습니다.
참고 자료
- https://docs.python.org/3/library/typing.html#typing.Union
- https://docs.python.org/3/library/functools.html#functools.reduce
⚠️ 알림: 이 분석은 AI가 실제 코드 diff를 기반으로 작성했습니다.
관련 포스트
- [cpython] CPython unicodedata.normalize() 최적화: Py_UCS4 버퍼 직접 조작으로 성능 향상
- [cpython] Python re 모듈의 findall, sub, subn 성능 개선: PyList_AppendTakeRef 도입
- [cpython] CPython 내부 들여다보기: logging.getLogger()는 어떻게 33% 더 빨라졌나?
- [cpython] tarfile 스트리밍 모드(r|*) 성능 개선: 파이썬 압축 파일 처리의 숨겨진 병목 제거
- [cpython] Python의 os.fork 후 발생하던 성능 프로파일링 충돌 문제 해결 및 최적화 분석
PR Analysis 의 다른글
- 이전글 [flashinfer] FlashInfer, Blackwell GPU를 위한 Gated MoE 커널 최적화로 성능 대폭 향상
- 현재글 : [cpython] CPython 최적화: functools.reduce 대신 Union 직접 사용하기
- 다음글 [vllm] [vLLM] CPU MoE 성능을 극대화하는 전략: 고정 임계값을 넘어선 동적 GEMM 디스패치 최적화
댓글