[SWE-009][중급] 느린 코드를 측정하고 빠르게 고치기 > IT 기술 공유

본문 바로가기
사이트 내 전체검색

IT 기술 공유

[SWE-009][중급] 느린 코드를 측정하고 빠르게 고치기

페이지 정보

profile_image
작성자 기술팀장
댓글 0건 조회 121회 작성일 26-09-04 11:33

본문

[이번 수업]

성능 최적화는 코드를 무조건 짧게 만드는 일이 아니라, 사용자가 기다리는 시간과 자원 사용량을 측정해 가장 큰 병목을 줄이는 일입니다. 이번에는 프로파일러로 느린 함수를 찾고, 같은 결과를 유지하면서 개선 효과를 재는 순서를 배웁니다.

[선수지식]

CS-006의 시간복잡도, TOOL-007의 디버거, PY-003의 리스트·집합을 알면 좋습니다. Python 3만 있으면 실습할 수 있습니다.

[학습목표]

1. 벤치마크와 프로파일링의 역할을 구분합니다.
2. 누적 실행 시간을 보고 병목 함수를 찾습니다.
3. 최적화 전후의 결과와 속도를 함께 검증합니다.

[핵심개념]

벤치마크는 같은 작업을 여러 번 실행해 시간, 처리량, 메모리 같은 값을 비교하는 측정입니다. 프로파일링은 실행 중 어떤 함수가 몇 번 호출되고 어디에서 시간이 쓰였는지 기록하는 과정입니다. 전체가 느리다는 사실은 벤치마크로 확인하고, 느린 위치는 프로파일러로 좁힙니다.

먼저 실제와 비슷한 입력과 목표를 정합니다. 응답 시간은 평균만 보지 말고 느린 요청을 나타내는 상위 백분위도 살펴야 합니다. CPU 계산, 파일·네트워크 대기, 메모리 할당은 병목 원인이 다르므로 알맞은 도구를 씁니다. 측정 자체에도 비용이 있으므로 프로파일러 결과를 벤치마크 시간처럼 해석하면 안 됩니다.

안전한 순서는 기준값 기록 → 병목 측정 → 한 가지 변경 → 테스트로 결과 확인 → 같은 조건에서 재측정입니다. 빠르지만 결과가 달라지거나 메모리를 지나치게 쓰면 개선이 아닙니다. 데이터 크기를 바꿔 성능 증가 추세도 확인합니다.

[따라하기]

아래를 profile_demo.py로 저장합니다. 리스트에서 중복을 제거하는 두 구현을 같은 입력으로 비교합니다.

```python
from timeit import repeat

values = list(range(3000)) * 3

def slow_unique(items):
    result = []
    for item in items:
        if item not in result:
            result.append(item)
    return result

def fast_unique(items):
    seen = set()
    result = []
    for item in items:
        if item not in seen:
            seen.add(item)
            result.append(item)
    return result

def fastest_ms(function):
    samples = repeat(lambda: function(values), number=3, repeat=5)
    return min(samples) * 1000 / 3

slow_result = slow_unique(values)
fast_result = fast_unique(values)
slow_ms = fastest_ms(slow_unique)
fast_ms = fastest_ms(fast_unique)
print("같은 결과:", slow_result == fast_result)
print("고유 값 수:", len(fast_result))
print(f"slow: {slow_ms:.2f} ms")
print(f"fast: {fast_ms:.2f} ms")
print("slow가 더 느림:", slow_ms > fast_ms)
```

macOS와 Linux는 `python3 profile_demo.py`, Windows PowerShell은 `py profile_demo.py`를 실행합니다. 시간 숫자는 컴퓨터마다 다르지만 다음 형태가 나옵니다.

```text
같은 결과: True
고유 값 수: 3000
slow: 환경에 따라 달라지는 값
fast: 환경에 따라 달라지는 값
slow가 더 느림: True
```

병목 위치는 macOS·Linux에서 `python3 -m cProfile -s cumulative profile_demo.py`, Windows에서 `py -m cProfile -s cumulative profile_demo.py`로 확인합니다. 표의 `cumtime`은 함수가 호출한 다른 함수의 시간까지 더한 누적 시간입니다. `slow_unique`가 큰 비중을 차지하는지 찾아보세요.

[흔한 실수]

느릴 것 같은 줄부터 고치거나 한 번 잰 값만 믿기 쉽습니다. 입력 크기, 준비 과정, 백그라운드 작업이 다른 측정도 비교할 수 없습니다. 작은 함수만 빠르게 만들어도 파일·데이터베이스 대기가 병목이면 사용자가 느끼는 시간은 줄지 않습니다.

[보안 주의]

프로파일에는 함수 이름, 파일 경로, 쿼리와 입력 정보가 남을 수 있습니다. 본인 소유의 로컬·격리 환경이나 허가된 시스템에서만 수집하고, 결과에서 개인정보와 비밀값을 제거하며 접근 권한과 보관 기간을 제한합니다. 상세 프로파일링은 부하를 늘릴 수 있으므로 공개 서비스 전체에 무기한 켜지 않습니다.

[직접 해볼 과제]

입력의 고유 값 수를 6000으로 늘린 뒤 두 시간을 다시 기록하세요. 결과가 같은지 먼저 확인하고, 입력이 두 배가 될 때 각 구현의 시간이 어떻게 달라지는지 표로 정리합니다.

[확인문제]

1. 벤치마크와 프로파일링은 각각 어떤 질문에 답하나요?
2. 최적화 뒤 기능 테스트를 다시 실행해야 하는 이유는 무엇인가요?
3. 프로파일러의 누적 시간을 벤치마크 결과로 쓰면 안 되는 이유는 무엇인가요?

[다음 학습]

다음 과정 MOBILE-009에서는 모바일 앱을 자동으로 시험하는 방법을 배웁니다. SWE 트랙은 확장성·일관성·가용성의 선택으로 이어집니다.

[공식 참고 자료]

- Python 프로파일러: https://docs.python.org/3/library/profile.html
- Python timeit: https://docs.python.org/3/library/timeit.html
- Python 메모리 추적: https://docs.python.org/3/library/tracemalloc.html
- Python 고해상도 시간 측정: https://docs.python.org/3/library/time.html#time.perf_counter
- 고해상도 시간 표준: https://www.w3.org/TR/hr-time-3/

댓글목록

등록된 댓글이 없습니다.

회원로그인

회원가입

사이트 정보

회사명 : 회사명 / 대표 : 대표자명
주소 : OO도 OO시 OO구 OO동 123-45
사업자 등록번호 : 123-45-67890
전화 : 02-123-4567 팩스 : 02-123-4568
통신판매업신고번호 : 제 OO구 - 123호
개인정보관리책임자 : 정보책임자명

접속자집계

오늘
4,900
어제
6,862
최대
16,772
전체
770,851
Copyright © 소유하신 도메인. All rights reserved.