구독 사용량을 트레이에서 보여 주는 개인 프로젝트(SessionMeter)를 만들면서, 계산부를 어떤 언어로 두는 게 나은지 확인하고 싶었습니다. 감으로 정하지 않으려고 같은 사양의 CLI 를 Rust·C++·Python 으로 각각 구현하고 같은 기계에서 쟀습니다.
무엇을 만들었나
사용량 스냅샷 JSON 을 읽어 제공자별로 최근 사용률·평균·최댓값을 집계하고, 남은 시간과 함께 텍스트 게이지로 그리는 CLI 입니다. JSON 파싱, 날짜 계산, 집계, 문자열 렌더링이 한 번씩 들어가 실제 코드와 성격이 비슷합니다.
$ gauge usage.json
antigravity [############............] 51.8% reset 3h 12m
claude [##################......] 74.0% reset 0h 48m
codex [###############.........] 61.7% reset 5h 03m- 세 구현의 출력은 바이트 단위로 같습니다(
--json출력으로 대조). - 각 언어에서 가장 흔한 선택지를 썼습니다. Rust 는 serde_json, C++ 는 단일 헤더 nlohmann/json, Python 은 표준 라이브러리 json 입니다.
측정 조건
아래 수치가 어떤 조건에서 나온 것인지 먼저 밝힙니다. 글을 쓰던 2026-09-07 에 한 번 잰 기록이고, 그 뒤로 다시 재지 않았습니다.
| 항목 | 값 |
|---|---|
| 운영체제 | Windows 11 |
| 툴체인 | rustc 1.98.1 · MSVC 14.51 · Python 3.14.6 |
| 빌드 옵션 | Rust --release · C++ /O2 /MT · Python PyInstaller onefile |
| 벤치 입력 | 20만 스냅샷이 든 16MB 단일 JSON 한 개 |
| 반복 | 3회, 그중 최소값 |
| 출력 대조 | 세 구현의 --json 결과를 바이트 단위로 비교 |
남기지 못한 것: CPU·메모리 사양, 실행 명령 전문, 3회 각각의 원시 측정값, 그리고 중앙값입니다. 최소값만 남겨 편차를 되짚을 수 없고, 세 구현의 코드도 지금은 남아 있지 않아 같은 조건의 독립 재현이 되지 않습니다. 그래서 아래 수치는 이 조건에서 한 번 관측된 값으로만 읽어야 하고, 언어 일반의 성능 순위로 옮겨 적을 수 없습니다.
처리 속도
Rust 가 C++ 보다 5배 빠른 것은 언어의 한계 성능 차이가 아니라 기본으로 고르게 되는 라이브러리 차이입니다. serde 는 JSON 을 구조체로 곧장 역직렬화하지만, nlohmann/json 은 먼저 범용 DOM 트리를 만듭니다. C++ 에서도 simdjson 같은 선택지를 쓰면 좁힐 수 있습니다. 다만 그 선택은 직접 찾아서 붙여야 합니다.
배포 산출물
Rust 와 C++ 는 실행파일 하나로 끝납니다(C++ 는 /MT 로 런타임을 정적 링크). Python 은 인터프리터를 통째로 넣어 9MB 가 되고, 실행할 때마다 압축을 풀어 임시 폴더에 펼치는 비용이 시작 시간에 더해집니다.
빌드
클린 빌드만 보면 C++(2.02초)가 Rust(5.48초)보다 빠릅니다. Rust 는 의존성까지 처음부터 컴파일하기 때문입니다. 그런데 개발 중에 반복되는 것은 한 줄 고치고 다시 빌드하기이고, 여기서는 Rust 가 0.71초로 앞섭니다. C++ 쪽은 단일 번역 단위라 매번 920KB 헤더를 다시 컴파일합니다.
코드 길이
이 구현에서는 Rust가 C++보다 4줄 길고, 파일·JSON·날짜 오류를 Result로 표현했습니다. 반환된 Result를 사용하지 않으면 기본 설정에서 unused_must_use 경고가 발생합니다. 경고를 오류로 승격하지 않는 한 컴파일 실패를 뜻하지 않으며, 타입만으로 모든 오류 처리가 보장되는 것도 아닙니다.
전체 측정값 표 펼치기
| 항목 | Rust | C++ (MSVC) | Python |
|---|---|---|---|
| 코드 줄 수(빈 줄 제외) | 157 | 153 | 99 |
| 의존성 확보 | Cargo.toml 두 줄 | 헤더 920KB 직접 내려받아 저장소에 포함 | 없음(표준 라이브러리) |
| 클린 빌드 | 5.48초 | 2.02초 | 15.38초(PyInstaller) |
| 재빌드(1줄 수정) | 0.71초 | 2.0초(전체 재컴파일) | 없음 |
| 실행파일 | 257KB | 389KB | 9,244KB |
| 빌드 중간 산출물 | 49MB(target/) | 수 MB(.obj) | 13MB(build/) |
| 20만 스냅샷 처리 | 104ms | 534ms | 990ms(스크립트) / 1,510ms(실행파일) |
| 시작 시간(작은 입력) | 51ms | 49ms | 115ms |
| 메모리 안전 | 안전한 Rust의 보장, unsafe·FFI 경계 별도 검증 | 직접 관리 | 런타임(GC) |
이 도구에서 Rust를 선택한 기준
세 언어 모두 이 CLI 를 만들 수 있습니다. 그래도 이런 성격의 도구(오래 켜 두고, 배포해서 남에게 주고, 데이터가 커질 수 있는 것)라면 Rust 를 권합니다. 이유는 속도 하나가 아닙니다.
- 배포가 끝난다: 257KB 실행파일 하나. 런타임 설치도, 버전 충돌도 없습니다.
- 빠른 쪽이 기본값이다: 가장 흔한 선택지(serde)가 이미 빠릅니다. C++ 에서 같은 속도를 내려면 라이브러리를 따로 찾아 붙여야 합니다.
- 고치는 속도가 빠르다: 반복되는 재빌드가 1초 아래라 흐름이 끊기지 않습니다.
- 실패 경로가 타입에 드러납니다:
Result경고를 오류로 승격하고 실패 경로를 테스트하면 누락을 줄일 수 있습니다.unsafe와 FFI 경계의 안전성은 별도 검증이 필요합니다. - 의존성 관리가 언어에 붙어 있다: 두 줄로 끝나는 일을, C++ 에서는 헤더를 내려받아 저장소에 넣는 것으로 해결해야 했습니다.
반대 방향도 분명합니다. 한 번 쓰고 버릴 분석 스크립트라면 Python 이 맞습니다. 99줄로 끝나고 빌드가 아예 없습니다. 기존 C++ 자산과 붙어야 하거나 특정 SDK 가 C++ 만 지원한다면 C++ 가 맞습니다. 이 비교는 '배포되는 작은 도구'라는 조건에서의 결론입니다.
수치의 조건과 한계는 앞의 측정 조건 절에 적어 두었습니다. 한 번의 측정 기록이고 원자료·중앙값이 없으므로, 이 글의 결론은 이 도구를 어떤 언어로 둘지에 대한 것이지 언어 일반의 성능 순위가 아닙니다.