시간차 분석 성능 최적화 (Time Lag Analysis Performance Optimization)
문제 상황
`analyze_time_lag` 명령어 실행 시 예상보다 훨씬 오래 걸리는 문제가 발생했습니다.
데이터 규모
- 뉴스 기사: 4,357개
- SNS 게시물: 469개
- 공통 키워드: 50개
- 총 게시물: 4,826개
원래 예상 시간
- 예상 시간: 약 3시간
원래 방식
def analyze_time_lag(keywords, days, ...):
# 1. compare_platforms() 호출 → 모든 게시물 형태소 분석 (1회)
comparison_result = compare_platforms(...)
keywords = [item['keyword'] for item in comparison_result['common_keywords']]
# 2. 각 키워드마다 get_keyword_occurrence_times() 호출
for keyword in keywords: # 50번 반복
# 뉴스에서 등장 시간 추출
news_times = get_keyword_occurrence_times(keyword, 'news', days, news_queryset)
# → 모든 뉴스 기사(4,357개)를 다시 형태소 분석
# SNS에서 등장 시간 추출
sns_times = get_keyword_occurrence_times(keyword, 'sns', days, sns_queryset)
# → 모든 SNS 게시물(469개)을 다시 형태소 분석
문제점
1. 중복 형태소 분석: 각 키워드마다 모든 게시물을 다시 형태소 분석
- 50개 키워드 × 4,357개 게시물 = 217,850번 형태소 분석
- 같은 게시물을 50번씩 반복 분석
2. 시간 복잡도: O(키워드 수 × 게시물 수 × 형태소 분석 시간)
- 형태소 분석 시간: 게시물당 약 0.05초
- 총 예상 시간: 217,850 × 0.05초 = 10,892초 = 약 3시간
3. 비효율적인 구조:
- `compare_platforms()`에서 이미 모든 게시물을 형태소 분석했지만
- 그 결과를 재사용하지 않고 다시 분석
최적화 방식
선택한 방법: 한 번만 형태소 분석하고 결과 재사용
def analyze_time_lag(keywords, days, ...):
# 1단계: 모든 뉴스 기사를 한 번만 형태소 분석
news_keywords_map = {} # {article_id: [keyword1, keyword2, ...]}
for article in news_queryset:
text = extract_text_from_news_article(article)
if text:
keywords = analyzer.extract_keywords(text, ...)
news_keywords_map[article.id] = keywords
# 2단계: 모든 SNS 게시물을 한 번만 형태소 분석
sns_keywords_map = {} # {post_id: [keyword1, keyword2, ...]}
for post in sns_queryset:
text = extract_text_from_sns_post(post)
if text:
keywords = analyzer.extract_keywords(text, ...)
sns_keywords_map[post.id] = keywords
# 3단계: 각 키워드의 등장 시간을 메모리에서 빠르게 계산
for keyword in keywords:
# 뉴스에서 등장한 게시물 찾기 (메모리 조회)
news_occurrences = [
article.published_at
for article in news_queryset
if article.id in news_keywords_map
and keyword in news_keywords_map[article.id]
]
# SNS에서 등장한 게시물 찾기 (메모리 조회)
sns_occurrences = [
post.published_at
for post in sns_queryset
if post.id in sns_keywords_map
and keyword in sns_keywords_map[post.id]
]
# 최초 등장 시간 계산
news_first = min(news_occurrences) if news_occurrences else None
sns_first = min(sns_occurrences) if sns_occurrences else None
개선 사항
1. 형태소 분석 횟수: 241,300번 → 4,357번 (1회만)
2. 시간 복잡도: O(키워드 수 × 게시물 수) → O(게시물 수 + 키워드 수 × 게시물 수)
- 형태소 분석: O(게시물 수) - 1회만
- 키워드 검색: O(키워드 수 × 게시물 수) - 메모리 조회 (매우 빠름)
검색하며 알았던 다른 방법들
방법 1: 역색인(Inverted Index) 사용
아이디어: 키워드 → 게시물 ID 리스트 매핑 생성
keyword_to_news = defaultdict(list) {keyword: [article_id1, article_id2, ...]}
keyword_to_sns = defaultdict(list) {keyword: [post_id1, post_id2, ...]}
for article in news_articles:
keywords = analyzer.extract_keywords(text)
for keyword in keywords:
keyword_to_news[keyword].append(article.id)
장점:
- 키워드 검색이 O(1)로 매우 빠름
- 메모리 효율적 (게시물 ID만 저장)
단점:
- 구현이 조금 더 복잡
- 키워드가 많을 경우 메모리 사용량 증가 가능
선택하지 않은 이유:
- 현재 방식도 충분히 빠르고 구현이 더 간단함
- 메모리 사용량이 크게 차이 나지 않음
방법 2: compare_platforms() 결과 재사용
아이디어: `compare_platforms()`에서 이미 형태소 분석을 했으므로 그 결과를 재사용
장점:
- 중복 분석 완전 제거
- 기존 함수 재사용
단점:
- `compare_platforms()` 함수 시그니처 변경 필요
- 다른 곳에서 사용하는 코드에 영향 가능
- 함수 간 결합도 증가
선택하지 않은 이유:
- 함수 간 결합도를 높이고 싶지 않음
- `analyze_time_lag()` 내부에서 독립적으로 처리하는 것이 더 명확함
선택한 방법의 이유
"한 번만 형태소 분석하고 결과 재사용" 방식을 선택한 이유
1. 구현 단순성 - 기존 함수 구조를 크게 변경하지 않음
- `analyze_time_lag()` 함수 내부에서만 수정
- 다른 함수에 영향 없음
2. 명확한 성능 개선 - 형태소 분석 횟수를 50배 감소 (241,300번 → 4,357번)
- 메모리 조회는 매우 빠르므로 실질적인 병목 제거
3. 메모리 효율성 - 게시물당 키워드 리스트만 저장 (약 수십 KB)
- 4,357개 게시물 × 평균 20개 키워드 = 약 100KB 정도
- 현대 시스템에서 무시할 수 있는 수준
4. 유지보수 용이성 - 로직이 한 곳에 집중되어 이해하기 쉬움
- 디버깅이 용이함
5. 확장성 - 키워드 수가 늘어나도 형태소 분석 횟수는 동일
- 게시물 수가 늘어나면 선형적으로 증가 (예상 가능)
성능 비교
| 항목 | 최적화 전 | 최적화 후 | 개선율 |
| 형태소 분석 횟수 | 241,300번 | 4,826번 | 99.0% 감소 |
| 예상 실행 시간 | 약 3시간 | 약 2분 내외 | 약 50배 빠름 |
| 시간 복잡도 | O(n×m×k) | O(n + m×k) | |
| 메모리 사용량 | 낮음 | 약 100KB 추가 | 큰 차이없음 |
시간 복잡도에 대해서 간단하게 추가설명을 하자면
변수 의미:
- n = 게시물 수 (4,826개)
- m = 키워드 수 (50개)
- k = 형태소 분석 시간 (게시물당 약 0.05초)
최적화 전: O(n × m × k)
의미: 각 키워드 마다 모든 게시물을 형태소 분석
- 총 연산 = n × m = 4,826 × 50 = 241,300번 형태소 분석
총 시간 = n * m * k = 4,826 * 50 * 0.05초 = 12,065초 ≈ 3.3시간
O(n * m * k) = 각 키워드마다 모든 게시물을 형태소 분석
최적화 후: O(n + m × k)
의미:
- 형태소 분석: 게시물 수만큼만 수행 (1회)
- 키워드 검색: 키워드 수 × 게시물 수 (메모리 조회)
- 1단계: 형태소 분석 = n = 4,826번 (한 번만)
2단계: 키워드 검색 = m * n = 50 × 4,826 = 241,300번 (메모리 조회)
- 총 시간 = (n * 형태소_분석_시간) + (m * n * 메모리_조회_시간)
- = (4,826 * 0.05초) + (241,300 * 거의_0초)
- ≈ 4-5분
실제 측정 결과
- 최적화 전: 측정 불가 (너무 오래 걸려 30분 정도 시행 중 중단)
- 최적화 후: 약 2-3분
- 개선율: 약 99% 시간 단축 (3-4시간 → 2-3분)
최적화 결과
================================================================================
시간차 분석 시작
================================================================================
분석 기간: 최근 7일
[INFO] 2026-01-09 15:12:08,260 services PyKOMORAN 형태소 분석기 초기화 완료 (모델: STABLE)
[INFO] 2026-01-09 15:12:08,313 services 불용어 파일 로드 완료: 884개 단어 (C:\Users\vhtmx\OneDrive\바탕 화면\trend\analyzer\data\stopwords_ko.txt)
[INFO] 2026-01-09 15:12:59,803 services 뉴스 기사 분석 완료: 4357개 기사, 20551개 키워드
[INFO] 2026-01-09 15:13:01,731 services SNS 게시물 분석 완료: 469개 게시물, 2980개 키워드
[INFO] 2026-01-09 15:13:01,734 services 플랫폼 비교 분석 완료: 뉴스 4357개, SNS 469개, 공통 키워드 50개
[INFO] 2026-01-09 15:13:01,738 services 뉴스 기사 형태소 분석 시작: 4357개
[INFO] 2026-01-09 15:13:53,635 services SNS 게시물 형태소 분석 시작: 469개
[INFO] 2026-01-09 15:13:55,571 services 형태소 분석 완료. 키워드별 등장 시간 계산 시작
[INFO] 2026-01-09 15:13:55,610 services 시간차 분석 완료: 4개 키워드, 뉴스→SNS 4개, SNS→뉴스 0개
[실행 시간]
--------------------------------------------------------------------------------
⏱️ 총 실행 시간: 108.75초 (1.81분)
[시간차 분석 통계]
--------------------------------------------------------------------------------
✅ 분석 완료: 4개 키워드
- 뉴스 → SNS: 4개 (100.0%)
- SNS → 뉴스: 0개 (0.0%)
- 동시 등장: 0개
- 뉴스 전용: 0개
- SNS 전용: 0개
- 뉴스 → SNS 평균 시간차: 81.22시간
[키워드별 분석 결과]
--------------------------------------------------------------------------------
📰 → 📱 뉴스 → SNS 전파:
1. 지구촌 시간차: 43.83시간 (뉴스: 2026-01-05 06:05, SNS: 2026-01-07 01:55)
2. 일화 시간차: 60.40시간 (뉴스: 2026-01-04 18:11, SNS: 2026-01-07 06:35)
3. 안성기 시간차: 109.71시간 (뉴스: 2026-01-02 17:27, SNS: 2026-01-07 07:10)
4. 배우 시간차: 110.94시간 (뉴스: 2026-01-02 16:13, SNS: 2026-01-07 07:10)
================================================================================
분석 완료
================================================================================
'AI_RSS_트래픽 프로젝트' 카테고리의 다른 글
| AI_RSS_분석_대용량트래픽 프로젝트 배포 (0) | 2026.03.20 |
|---|---|
| 모르는 상태로 하는 RSS&분석&RAG 프로젝트(19) 트렌드 분석 (0) | 2026.01.14 |
| 모르는 상태로 하는 RSS&분석&RAG 프로젝트(17) 시간차 분석 (뉴스 ↔ SNS 전파 패턴) (0) | 2026.01.09 |
| 모르는 상태로 하는 RSS&분석&RAG 프로젝트(16) 크로스 플랫폼 키워드 추출 및 빈도 분석 (0) | 2026.01.02 |
| 모르는 상태로 하는 RSS&분석&RAG 프로젝트(15) 크로스 플랫폼 키워드 추출 및 빈도 분석 (0) | 2025.12.30 |