Python list comprehension이 for문보다 빠른 진짜 이유
문제 발생
"컴프리헨션이 더 빠르다"는 이야기만 듣고 모든 반복문을 억지로 컴프리헨션으로 바꾸다가 오히려 가독성만 나빠지는 경우가 있습니다. 실제로 왜, 얼마나 빠른지 정확히 알아야 합리적으로 선택할 수 있습니다.
# 일반 for문
result = []
for x in range(1000):
result.append(x * 2)
# 컴프리헨션
result = [x * 2 for x in range(1000)]원인 분석
두 코드의 차이는 두 가지입니다.
- 속성 조회(attribute lookup) 횟수:
result.append(...)는 매 반복마다result객체에서append메서드를 조회하는 과정을 거칩니다. 컴프리헨션은 CPython 내부적으로LIST_APPEND라는 전용 bytecode 명령을 사용해 이 조회 과정을 건너뜁니다. - 함수 호출 오버헤드: 컴프리헨션은 내부적으로 별도의 코드 객체로 컴파일되어 실행되며, 일반 함수 호출보다 가벼운 방식으로 최적화되어 있습니다.
CPython 공식 문서와 dis 모듈로 bytecode를 비교하면 컴프리헨션 쪽의 명령 수가 더 적은 것을 직접 확인할 수 있습니다.
import dis
dis.dis("[x*2 for x in range(10)]")다만 이 차이는 요소당 작업이 단순할 때(단순 변환/필터링) 두드러집니다. 컴프리헨션 안에서 무거운 함수를 호출한다면 그 함수 호출 비용이 지배적이라 컴프리헨션과 for문의 차이는 무시할 수준으로 작아집니다.
해결 방안
- 단순 변환/필터링(예:
[f(x) for x in items if condition(x)])은 컴프리헨션이 더 빠르고 파이썬스럽습니다(Pythonic). - 컴프리헨션 안의 로직이 복잡해져서(중첩 조건, 여러 줄) 한눈에 읽기 어려워지면 가독성을 위해 일반 for문으로 되돌리는 편이 낫습니다 — 속도보다 유지보수성이 우선입니다.
- 결과를 리스트로 모두 들고 있을 필요가 없다면(한 번씩만 순회) 제너레이터 표현식(
(x*2 for x in items), 대괄호 대신 소괄호)을 쓰면 메모리를 절약할 수 있습니다 — 대용량 데이터를 다룰 때 특히 중요합니다. - 딕셔너리/셋 컴프리헨션(
{k: v for ...},{x for ...})도 같은 원리로 일반 반복문보다 유리합니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.