파이썬 프로그램 시작 78초를 20초로 — 로그 타임라인으로 병목 찾기
N100 미니PC에서 돌아가는 파이썬 자동화 프로그램이 있는데, 처음 실행할 때 78초가 걸렸다. 프로그램 종료 후 다시 실행하면 또 78초. 로딩 화면만 1분 넘게 보고 있는 게 너무 불편해서 드디어 손을 댔다. 로그에 타임스탬프를 촘촘하게 찍어서 타임라인으로 만들어보니 원인이 명확하게 보였다. 총 58초를 줄여서 20초 이하로 만들었다.
78초
최적화 전 시작 시간
~20초
최적화 후 시작 시간
58초
단축된 시간
4가지
개선 항목
1N100에서 78초짜리 시작 화면
이 프로그램은 매일 자동으로 재시작되는 구조다. 에러가 생기면 자동 재시작, 새벽에 스케줄 재시작. 하루에 3~5번은 재시작이 되는데 그때마다 78초짜리 로딩이 발생했다. 매번 봐야 하는 입장에서는 꽤 짜증나는 수준이었다.
N100은 저전력 미니PC용 프로세서라 고성능 서버 CPU와 비교하면 느리다. 그래도 78초는 너무했다. 78초면 뭔가 기다리는 게 있다는 뜻이었다. I/O 바운드, 아마도 네트워크 요청.
최적화 전 시작 순서 (추정)
"초기화 시작... 뭔가 로딩 중... 로딩 중... 완료" 수준의 로그만 있어서 어디서 시간을 먹는지 알 수 없었다. 가장 먼저 한 것은 로그 개선이었다.
2로그 타임라인으로 병목 찾기
시작 과정의 각 단계마다 타임스탬프가 찍힌 로그를 추가했다. 초기화 함수 진입/완료, 외부 API 호출 전후, 각 모듈 로드 완료 시점 등.
# 타임스탬프 로그 추가 패턴
import time
import logging
class TimedLogger:
def __init__(self):
self.start = time.time()
def log(self, msg: str):
elapsed = time.time() - self.start
logging.info(f"[{elapsed:.2f}s] {msg}")
# 사용
timer = TimedLogger()
timer.log("초기화 시작")
# ... 자동 로그인 ...
timer.log("자동 로그인 완료")
# ... GitHub API 호출 ...
timer.log("배너 데이터 로드 완료")
# ... 기타 초기화 ...
timer.log("준비 완료")# 실제 로그 출력 (최적화 전)
[0.00s] 초기화 시작 [0.12s] DB 연결 완료 [3.45s] 설정 파일 로드 완료 [13.52s] 자동 로그인 완료 ← 10초 소요 [56.89s] 배너 데이터 로드 완료 ← 43초 소요!! [66.91s] 하트비트 트래커 시작 [76.93s] 자동 시작 대기 완료 ← 10초 대기 [77.01s] 준비 완료 ← 총 77초
타임라인을 보자마자 원인이 보였다. 배너 데이터 로드가 43초. 전체 78초 중 55%를 여기서 먹고 있었다.
3병목 1: GitHub API 호출 44회 → 5회로 줄임 (43초 절약)
배너 데이터라는 게 뭔지 코드를 열어보니 GitHub API로 특정 레포지토리의 파일 목록을 가져오는 로직이었다. 문제는 한 번에 44개의 개별 API 호출을 하고 있었다는 것. GitHub API는 요청당 평균 1초쯤 걸리니까 44회 × 1초 = 44초. 딱 맞아떨어졌다.
# 기존 코드 — 개별 호출 44회
# 파일마다 개별 API 호출
for banner_id in banner_ids: # 44개
response = github_api.get_content(
repo="my-org/banners",
path=f"banners/{banner_id}.json"
)
banners.append(parse_banner(response))# 개선 코드 — 디렉토리 목록 1회 + 패턴 매칭
# 1. 디렉토리 전체 목록 한 번에 가져옴 (API 1회)
all_files = github_api.get_contents(
repo="my-org/banners",
path="banners/"
)
# 2. 패턴 매칭으로 필요한 파일만 선별 (API 없음)
target_files = [
f for f in all_files
if f.name.startswith("banner_") and f.name.endswith(".json")
and extract_id(f.name) in banner_ids
]
# 3. 필요한 파일만 가져옴 (API ~5회)
for f in target_files[:5]: # 상위 5개만
content = github_api.get_content(repo="my-org/banners", path=f.path)
banners.append(parse_banner(content))절감 효과: 43초
API 호출이 44회 → 약 5회로 줄면서 43초가 사라졌다. 사실 44개를 전부 가져올 필요도 없었다. 최신 5개만 있으면 충분한 로직이었는데 코드가 오래되다 보니 이런 비효율이 쌓여있었다.
4병목 2: 자동 로그인 대기 10초 → 3초로 단축 (7초 절약)
자동 로그인 후 "로그인이 완료될 때까지 10초 대기"라는 코드가 있었다. 페이지 전환 확인 없이 그냥 10초를 기다리는 방식이었다. 처음에 누군가 "10초면 충분하겠지"라고 넣은 것 같다.
# 기존 — 무조건 10초 대기
login_button.click() time.sleep(10) # 10초 기다림
# 개선 — 실제 완료 감지 + 최대 대기 3초
login_button.click()
# 로그인 완료 조건 감지 (URL 변경 또는 특정 요소 등장)
WebDriverWait(driver, timeout=3).until(
lambda d: "login" not in d.current_url
or EC.presence_of_element_located((By.ID, "user-menu"))(d)
)
# 완료되면 바로 다음 단계로. 최대 3초 대기실제 로그인은 대부분 1~2초 안에 완료됐다. WebDriverWait로 바꾸니 평균 1.5초로 줄었고, 최대 대기를 3초로 제한했다.
5병목 3: 미사용 기능 비활성화 (8초 절약)
로그 타임라인에서 두 가지 미사용 기능을 발견했다.
하트비트 트래커 — 완전 비활성화 (약 3초)
외부 서버에 "나 살아있어" 신호를 보내는 하트비트 기능이 있었는데, 해당 서버가 더 이상 없었다. 그런데도 초기화 시 연결을 시도하다가 타임아웃이 나는 구조. 기능 전체를 비활성화하니 연결 시도 시간이 사라졌다.
자동 시작 10초 대기 → 3초로 단축 (7초)
프로그램 준비 완료 후 자동으로 작업을 시작하기 전에 10초 대기하는 로직이 있었다. "사용자가 취소할 기회를 주기 위해" 넣은 것 같은데, 이 프로그램은 서버에서 돌아서 사람이 보고 있지 않는다. 3초로 줄였다.
6결과: 78초 → 20초
| 항목 | 최적화 전 | 최적화 후 | 절감 |
|---|---|---|---|
| GitHub API 호출 | 44회 (~43초) | ~5회 (~5초) | ~38초 |
| 자동 로그인 대기 | 고정 10초 | 평균 1.5초 | ~8초 |
| 하트비트 트래커 | 타임아웃 (~3초) | 비활성화 (0초) | ~3초 |
| 자동 시작 대기 | 고정 10초 | 3초 | 7초 |
| 합계 | ~78초 | ~20초 | ~58초 |
핵심 교훈
성능 최적화의 첫 단계는 측정이다. "느린 것 같다"는 느낌으로 아무 코드나 건드리기 전에 로그 타임라인으로 정확한 병목을 찾아야 한다. 이번에는 전체 시간의 55%가 API 호출 한 곳에서 나왔고, 그것도 호출 횟수를 줄이는 단순한 방법으로 해결됐다.
요약 체크리스트
파이썬 시작 속도 최적화 핵심
- ✓먼저 로그 타임라인을 만들어서 어디서 시간을 먹는지 정확히 파악한다
- ✓외부 API 호출은 시작 시 반복 호출을 최소화 — 디렉토리 1회 조회 후 패턴 매칭
- ✓time.sleep() 고정 대기는 WebDriverWait나 폴링으로 바꿔서 실제 완료 감지
- ✓더 이상 쓰지 않는 기능(하트비트, 미사용 초기화 등)은 완전 비활성화
- ✓N100 같은 저사양 하드웨어일수록 I/O 병목 최적화 효과가 크다
본 글은 2026년 3월 실제 경험을 바탕으로 작성되었습니다. 성능 수치는 환경에 따라 다를 수 있습니다. 본 콘텐츠의 비상업적 공유는 자유이나, 상업적 이용 시 문의 페이지를 통해 연락 바랍니다.
댓글
(3개)로그인하면 댓글을 작성할 수 있습니다.
로그에 타임스탬프 찍어서 타임라인 분석하는 방법 진짜 기본인데 막상 실무에서 안 하는 경우가 많죠. 저도 이걸로 숨은 병목 여러 개 찾았습니다.
N100에서 78초라니 공감됩니다 ㅋㅋ 저도 비슷한 미니PC 쓰는데 무거운 걸 돌리면 체감이 많이 다르더라고요.
GitHub API 호출 횟수 최적화가 핵심이었군요. API 응답 캐싱이나 배치 처리로도 해결할 수 있을 것 같은데, 패턴 매칭으로 미리 필터링한 아이디어가 더 깔끔해 보입니다.
관련 글
© 2026 TreeRU. All rights reserved.
본 콘텐츠의 저작권은 TreeRU에 있으며, 출처를 밝히지 않은 무단 전재 및 재배포를 금합니다. 인용 시 출처(treeru.com)를 반드시 명시해 주세요.