-
Notifications
You must be signed in to change notification settings - Fork 0
Performance Benchmarks
pytmux 는 성능을 추측이 아니라 측정으로 관리한다. 매 푸시마다 GitHub Actions 가 macOS·Linux·Windows 세 OS에서 헤드리스 벤치마크를 돌려 결과를 저장소에 미러링하고, 이 페이지는 그 최신 수치(2026-06-20 기준)와 2주간의 추세를 정리한다.
측정값 출처:
docs/benchmark/{darwin-arm64,linux-x86_64,windows-amd64}/. 생성기:scripts/bench.py· 워크플로:.github/workflows/benchmark.yml.
벤치마크는 전부 헤드리스다. 실제 터미널·셸·ssh 가 없어도, 합성 입력을 코어에 직접 먹여(드라이브) 순수 코드 경로의 비용만 잰다. 덕분에 OS·CI 환경 차이를 빼면 수치 변동이 곧 우리 코드 변경의 효과가 된다.
-
CI 매트릭스: GitHub Actions 의
ubuntu/macos/windows러너가 push 마다 동일 시나리오를 측정한다. 결과는 OS별 JSON·Markdown 으로 저장소에 커밋된다. -
반복 수: 워크로드당
reps=200(콜드 import 는 별도 프로세스n=5), 탭 12개·활성 패널 6개, flood 8 MB. -
신호 판단: CI 러너는 공유 클라우드 VM 이라
max·p99꼬리에 노이즈가 섞인다. 추세는 일별 중앙값(median) 을 1차 신호로, 단발값은 보조로 읽는다.
측정 3축은 ① 시작 시간 ② 다중 탭/패널 반응성 ③ 출력 폭증(처리량·프레임 지연)이다. 아래 표의 시간 단위는 모두 ms 이며, 부드러운 입력의 기준선은 60fps = 16.7 ms, 30fps = 33.3 ms 슬라이스 예산이다.
| 카테고리 | 무엇을 재나 | 좋은 방향 |
|---|---|---|
| 시작 시간 | 콜드 import(별도 프로세스), 프레임워크 init(Server+세션+첫 layout, 셸 제외) | 낮을수록 |
| 탭/패널 반응성 | layout 메시지 빌드·직렬화, 전 패널 render+직렬화, 탭 전환 | 낮을수록 |
| 출력 폭증 | feed 처리량(MB/s), 슬라이스 지연(p50/p99/max), 프레임당 render | MB/s 높을수록·ms 낮을수록 |
| 메모리/프로세스 비용 | 탭/패널당 프로세스 생성 비용(특히 Windows의 PTY 호스트) | 낮을수록 |
메모리는 CI 벤치마크 JSON 에 별도 수치 표가 없고, 프로세스 모델 차원에서 정성적으로 다룬다(§5). pytmux 는 단일 서버(데몬)–다중 클라이언트 구조라 탭이 늘어도 코어 메모리는 완만하게 증가하지만, Windows 는 탭 하나당 PTY 호스트 프로세스가 따로 뜨는 게 지배적 비용이다.
환경: Linux CPython 3.12.13 / 6.17.0-azure · macOS CPython 3.12.10 / Darwin 24.6.0
· Windows CPython 3.12.10 / Windows 2025Server. 공통 의존성 textual 8.2.7, wcwidth 0.8.1.
| 항목 | macOS | Linux | Windows |
|---|---|---|---|
| cold import p50 | 60.8 ms | 56.8 ms | 82.9 ms |
| cold import p99 | 82.5 ms | 71.4 ms | 101.7 ms |
| framework init p50 | 2.29 ms | 3.49 ms | 3.95 ms |
콜드 import 가 시작 비용의 대부분이며, 이는 사실상 Python 인터프리터 기동 + 모듈 import 비용이다. pytmux 자체의 init 로직(플러그인 load 포함)은 수 ms 로 무시할 수준이다.
| 작업 (매 프레임/이벤트) | macOS | Linux | Windows |
|---|---|---|---|
| layout 빌드+직렬화 p50 | 0.027 ms | 0.034 ms | 0.033 ms |
| 전 패널 render+직렬화 p50 | 0.052 ms | 0.069 ms | 0.066 ms |
| 탭 전환(select+layout) p50 | 0.007 ms | 0.009 ms | 0.009 ms |
세 OS 모두 정상 상태 재렌더가 60fps 예산 대비 2~3 자릿수의 여유를 갖는다. 탭을 12개 띄우고 활성 윈도우에 6패널을 배치해도 한 프레임의 코어 비용이 0.1 ms 미만이다.
| 워크로드 | OS | feed MB/s | slice p50 | slice p99 | render ms/frame |
|---|---|---|---|---|---|
| claude_busy 200×50 (alt 풀리페인트) | macOS | 0.82 | 8.08 | 26.7 | 4.27 |
| Linux | 0.64 | 12.36 | 20.4 | 5.53 | |
| Windows | 0.68 | 11.50 | 20.4 | 5.34 | |
| plain_cat 200×50 (main 스크롤) | macOS | 0.85 | 7.94 | 22.9 | 3.06 |
| Linux | 0.57 | 13.06 | 27.7 | 4.61 | |
| Windows | 0.62 | 12.07 | 34.1 | 4.47 | |
| claude_busy 80×24 (원격 흔한 크기) | macOS | 0.84 | 7.10 | 20.5 | 0.70 |
| Linux | 0.59 | 12.21 | 19.9 | 1.03 | |
| Windows | 0.63 | 11.57 | 20.4 | 0.99 |
풀리페인트 프레임 비용(render ms/frame)은 전 OS에서 60fps 예산 안이다. 처리량은
워크로드가 합성 입력에 묶여 있어 변동이 작으며, macOS(Apple Silicon)가 처리량·프레임
양쪽에서 가장 빠르다.
| 지표 (현재 median) | macOS | Linux | Windows | 해석 |
|---|---|---|---|---|
| cold import p50 | ~61 ms | ~57 ms | ~83 ms | Windows 가 인터프리터 기동·import 부담 최대 |
| 전 패널 render p50 | 0.052 | 0.069 | 0.066 | 셋 다 사실상 무료 |
| claude_busy200 frame | 4.27 | 5.53 | 5.34 | macOS 최속(Apple Silicon) |
| claude_busy200 feed | 0.82 MB/s | 0.64 MB/s | 0.68 MB/s | macOS 처리량 우위 |
| plain_cat slice p99 | 22.9 | 27.7 | 34.1 ⚠ | Windows 꼬리가 30fps 경계 근접 |
차이를 만드는 요인:
- CPU/메모리 대역폭 — macOS arm64 가 feed 처리량과 프레임 비용 양쪽에서 앞선다. CPU 바운드인 VT 파싱·셀 직렬화 경로가 그대로 칩 성능을 반영한다.
- 인터프리터 기동 + import — 콜드 import 절대값은 Windows 가 가장 크다. 프로세스 생성 비용 자체가 Windows 에서 비싸기 때문이며, pytmux 코드 탓이 아니다.
-
PTY 호스트 모델 — Windows 는 탭/패널 하나를 새로 열 때
CreatePseudoConsole이 PTY 호스트 프로세스를 즉시 spawn 한다. 멀티바이트 무손상 스트리밍을 위해 번들 콘솔 호스트를 쓰는데, 이 선택이 시스템 기본 대비 ~40 ms 를 더 쓰지만 출력 정확성을 보장하는 의도된 비용이다. 자세한 배경은 Why-pytmux-on-Windows 참고.
전 지표에서 모든 OS가 60fps/30fps 예산 안의 정상 작동 영역에 있다. 유일하게 예산에
근접하는 건 plain_cat 슬라이스 p99 꼬리뿐이며, 이는 §6의 추적 항목과 같은 지표다.
CI 벤치마크는 RSS 수치를 표로 수집하지 않지만, 프로세스 모델 차원의 비용은 명확하다.
- 단일 서버–다중 클라이언트: 모든 세션·탭은 하나의 데몬(단일 asyncio 루프) 안에 산다. 탭이 늘어도 새 인터프리터가 뜨지 않으므로 코어 메모리 증가는 완만하다.
- 셸 프로세스: 패널마다 셸 프로세스 1개. 이는 어떤 멀티플렉서든 본질적 비용이다.
- Windows 추가 비용: 패널 하나당 PTY 호스트 프로세스가 추가로 1개 더 뜬다 (즉 탭당 프로세스 2개). 새 탭/패널 생성이 ~250–350 ms 걸리는 주원인이며, 이는 Windows 프로세스 생성 비용 + 콘솔 호스트 spawn 의 합이다.
macOS/Linux 는 PTY 가 커널 객체라 추가 호스트 프로세스가 없다. 플랫폼별 동작 차이 전반은 Platform-Differences 에 정리돼 있다.
2주간 OS당 약 400 run(총 ~1,200 run)을 누적해 본 큰 그림:
초기 베이스라인을 한 번 찍은 직후, 렌더 경로 최적화가 착륙해 render_all p50 이 세
OS에서 동시에 ~99% 하강했다. 핵심은 라이브 뷰에서 변경된(dirty) 행만 재직렬화하고
나머지는 행 캐시를 재사용하는 것이다. 정상 상태 재렌더가 사실상 공짜가 됐다.
| OS | 최적화 전 | 최적화 후 | 변화 |
|---|---|---|---|
| Linux | 8.66 ms | 0.07 ms | −99.2% |
| macOS | 4.54 ms | 0.05 ms | −99.0% |
| Windows | 7.56 ms | 0.07 ms | −99.2% |
같은 스프린트가 풀리페인트 프레임 비용도 약 절반으로(예: Linux 10.3→5.7 ms), 콜드 import 도 한 단(약 −30%) 끌어내렸다. 이후 2주간 무회귀로 평탄 유지됐다 — 코드가 빠르게 늘어나는 기간에도 핵심 성능 지표를 지킨 셈이다.
plain_cat 200×50(메인 스크롤)의 슬라이스 p99 가 06-18 부터 Linux/Windows 에서만
상승했다(Linux ~+13%, Windows ~+21%). 같은 기간 macOS 는 오히려 하강해, 전형적인
OS 비대칭 회귀 신호다.
- 시점이 클라이언트 경로의 기능 작업과 겹친다.
- 절대 크기는 수 ms 로 작고 합성 flood 의 꼬리 지표지만, macOS 엔 없고 두 OS 에만 나타나는 비대칭이라 추적 대상으로 남겼다.
이것이 벤치마크 매트릭스의 가치다. 단일 머신에선 보이지 않았을 OS 비대칭 회귀를, 세 OS를 매 푸시마다 측정하기 때문에 작은 단계에서 포착한다.
framework_init 의 first/last 단발값은 ±15~36% 흔들리지만 일별 중앙값으로 보면 추세가
아니라 CI 러너 노이즈다(간헐 스파이크 max 가 큼). 단발 비교를 신뢰하지 않고 중앙값
추세를 1차 신호로 삼는 이유다.
- 성능 개선의 거의 전부는 렌더 dirty-행 캐시 한 번의 스프린트에서 나왔고, 이후 2주는 무회귀로 평탄하다.
- 현재 모든 OS가 60fps/30fps 예산 안의 정상 작동 영역에 있다.
- macOS(Apple Silicon)가 처리량·프레임에서 최속, Windows 가 시작 비용·꼬리 지연에서 가장 무겁다 — 대부분 OS의 프로세스/콘솔 모델에서 비롯되며 코드 회귀가 아니다.
- 유일한 추적 항목은 Linux/Windows 의
plain_cat슬라이스 p99 미세 상승이며, CI 매트릭스가 OS 비대칭으로 포착했다.
소개 · 사용
- Project-Overview
- User-Manual
- Screenshots
- Settings-Popup
- Single-Session-Model
- Tmux-Feature-Comparison
플러그인
Claude Code 플러그인
- Claude-Code-Plugins
- Dev-Guide-claude-code
- Dev-Guide-claude-token-usage-view
- Dev-Guide-claude-prompt-history
- Dev-Guide-claude-resume
- Dev-Guide-claude-disable-feedback
플랫폼 · 성능
품질 · 보안
리뷰·분석 보고서
연혁
기여