treeru.com
개발

파이썬 프로그램 시작 78초를 20초로 - 로그 타임라인으로 병목 찾기

2026-03-25
Treeru

저전력 미니PC에서 돌아가는 파이썬 자동화 프로그램이 있는데, 처음 실행할 때 78초가 걸렸다. 프로그램 종료 후 다시 실행하면 또 78초. 로딩 화면만 1분 넘게 보고 있는 게 너무 불편해서 드디어 손을 댔다. 로그에 타임스탬프를 촘촘하게 찍어서 타임라인으로 만들어보니 원인이 명확하게 보였다. 총 58초를 줄여서 20초 이하로 만들었다.

78초

최적화 전 시작 시간

~20초

최적화 후 시작 시간

58초

단축된 시간

4가지

개선 항목

1저전력 미니PC에서 78초짜리 시작 화면

이 프로그램은 매일 자동으로 재시작되는 구조다. 에러가 생기면 자동 재시작, 새벽에 스케줄 재시작. 하루에 3~5번은 재시작이 되는데 그때마다 78초짜리 로딩이 발생했다. 매번 봐야 하는 입장에서는 꽤 짜증나는 수준이었다.

저사양 미니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초
시작 단계 4종의 최적화 전 대 후 소요시간 그룹막대 그래프. GitHub API 호출 43초에서 5초, 자동 로그인 대기 10초에서 1.5초, 하트비트 트래커 3초에서 0초, 자동 시작 대기 10초에서 3초. GitHub API 호출 막대가 압도적으로 크다
단계별 최적화 전(파랑)·후(초록) 소요시간(초, 초 단위 근사값). 하트비트 트래커는 완전 비활성화로 0초.

핵심 교훈

성능 최적화의 첫 단계는 측정이다. "느린 것 같다"는 느낌으로 아무 코드나 건드리기 전에 로그 타임라인으로 정확한 병목을 찾아야 한다. 이번에는 전체 시간의 55%가 API 호출 한 곳에서 나왔고, 그것도 호출 횟수를 줄이는 단순한 방법으로 해결됐다.

요약 체크리스트

파이썬 시작 속도 최적화 핵심

  • 먼저 로그 타임라인을 만들어서 어디서 시간을 먹는지 정확히 파악한다
  • 외부 API 호출은 시작 시 반복 호출을 최소화: 디렉토리 1회 조회 후 패턴 매칭
  • time.sleep() 고정 대기는 WebDriverWait나 폴링으로 바꿔서 실제 완료 감지
  • 더 이상 쓰지 않는 기능(하트비트, 미사용 초기화 등)은 완전 비활성화
  • 저사양 미니PC일수록 I/O 병목 최적화 효과가 크다

본 글은 2026년 3월 실제 경험을 바탕으로 작성되었습니다. 성능 수치는 환경에 따라 다를 수 있습니다. 본 콘텐츠의 비상업적 공유는 자유이나, 상업적 이용 시 문의 페이지를 통해 연락 바랍니다.

파이썬 자동화 성능 개선이 필요하신가요?

시작 속도 최적화, API 호출 효율화, 병목 분석까지. 실제 운영 환경 기준으로 실용적인 개선을 도와드립니다.

자동화 개발 상담 신청
T

Treeru

웹 개발, IT 인프라, AI 솔루션 분야의 실무 인사이트를 공유합니다. 기업의 디지털 전환을 돕는 IT 파트너, Treeru입니다.

공유

관련 글

© 2026 TreeRU. All rights reserved.

본 콘텐츠의 저작권은 TreeRU에 있으며, 출처를 밝히지 않은 무단 전재 및 재배포를 금합니다. 인용 시 출처(treeru.com)를 반드시 명시해 주세요.