같은 CLI 를 Rust·C++·Python 으로 만들어 보고 Rust 를 고른 이유

세션 사용량 게이지의 계산부만 떼어 세 언어로 같은 사양을 구현했습니다. 코드 길이, 빌드, 실행파일, 처리 속도를 같은 조건에서 재고 비교했습니다.

구독 사용량을 트레이에서 보여 주는 개인 프로젝트(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회 각각의 원시 측정값, 그리고 중앙값입니다. 최소값만 남겨 편차를 되짚을 수 없고, 세 구현의 코드도 지금은 남아 있지 않아 같은 조건의 독립 재현이 되지 않습니다. 그래서 아래 수치는 이 조건에서 한 번 관측된 값으로만 읽어야 하고, 언어 일반의 성능 순위로 옮겨 적을 수 없습니다.

처리 속도

Rust104 ms
C++534 ms
Python 스크립트990 ms
Python 실행파일1,510 ms
20만 스냅샷 입력, 3회 중 최소값. 낮을수록 짧은 처리 시간입니다.

Rust 가 C++ 보다 5배 빠른 것은 언어의 한계 성능 차이가 아니라 기본으로 고르게 되는 라이브러리 차이입니다. serde 는 JSON 을 구조체로 곧장 역직렬화하지만, nlohmann/json 은 먼저 범용 DOM 트리를 만듭니다. C++ 에서도 simdjson 같은 선택지를 쓰면 좁힐 수 있습니다. 다만 그 선택은 직접 찾아서 붙여야 합니다.

배포 산출물

Rust257 KB
C++389 KB
Python onefile9,244 KB
같은 측정 기록의 실행파일 크기입니다.

Rust 와 C++ 는 실행파일 하나로 끝납니다(C++ 는 /MT 로 런타임을 정적 링크). Python 은 인터프리터를 통째로 넣어 9MB 가 되고, 실행할 때마다 압축을 풀어 임시 폴더에 펼치는 비용이 시작 시간에 더해집니다.

빌드

Rust 클린5.48 초
Rust 재빌드0.71 초
C++2.02 초
Python 패키징15.38 초
클린 빌드·재빌드·패키징은 서로 다른 작업이므로 구분해서 읽습니다.

클린 빌드만 보면 C++(2.02초)가 Rust(5.48초)보다 빠릅니다. Rust 는 의존성까지 처음부터 컴파일하기 때문입니다. 그런데 개발 중에 반복되는 것은 한 줄 고치고 다시 빌드하기이고, 여기서는 Rust 가 0.71초로 앞섭니다. C++ 쪽은 단일 번역 단위라 매번 920KB 헤더를 다시 컴파일합니다.

코드 길이

Python99 줄
C++153 줄
Rust157 줄
빈 줄을 제외한 해당 구현의 코드 줄 수입니다.

이 구현에서는 Rust가 C++보다 4줄 길고, 파일·JSON·날짜 오류를 Result로 표현했습니다. 반환된 Result를 사용하지 않으면 기본 설정에서 unused_must_use 경고가 발생합니다. 경고를 오류로 승격하지 않는 한 컴파일 실패를 뜻하지 않으며, 타입만으로 모든 오류 처리가 보장되는 것도 아닙니다.

전체 측정값 표 펼치기
항목RustC++ (MSVC)Python
코드 줄 수(빈 줄 제외)15715399
의존성 확보Cargo.toml 두 줄헤더 920KB 직접 내려받아 저장소에 포함없음(표준 라이브러리)
클린 빌드5.48초2.02초15.38초(PyInstaller)
재빌드(1줄 수정)0.71초2.0초(전체 재컴파일)없음
실행파일257KB389KB9,244KB
빌드 중간 산출물49MB(target/)수 MB(.obj)13MB(build/)
20만 스냅샷 처리104ms534ms990ms(스크립트) / 1,510ms(실행파일)
시작 시간(작은 입력)51ms49ms115ms
메모리 안전안전한 Rust의 보장, unsafe·FFI 경계 별도 검증직접 관리런타임(GC)

이 도구에서 Rust를 선택한 기준

세 언어 모두 이 CLI 를 만들 수 있습니다. 그래도 이런 성격의 도구(오래 켜 두고, 배포해서 남에게 주고, 데이터가 커질 수 있는 것)라면 Rust 를 권합니다. 이유는 속도 하나가 아닙니다.

  1. 배포가 끝난다: 257KB 실행파일 하나. 런타임 설치도, 버전 충돌도 없습니다.
  2. 빠른 쪽이 기본값이다: 가장 흔한 선택지(serde)가 이미 빠릅니다. C++ 에서 같은 속도를 내려면 라이브러리를 따로 찾아 붙여야 합니다.
  3. 고치는 속도가 빠르다: 반복되는 재빌드가 1초 아래라 흐름이 끊기지 않습니다.
  4. 실패 경로가 타입에 드러납니다: Result 경고를 오류로 승격하고 실패 경로를 테스트하면 누락을 줄일 수 있습니다. unsafe와 FFI 경계의 안전성은 별도 검증이 필요합니다.
  5. 의존성 관리가 언어에 붙어 있다: 두 줄로 끝나는 일을, C++ 에서는 헤더를 내려받아 저장소에 넣는 것으로 해결해야 했습니다.

반대 방향도 분명합니다. 한 번 쓰고 버릴 분석 스크립트라면 Python 이 맞습니다. 99줄로 끝나고 빌드가 아예 없습니다. 기존 C++ 자산과 붙어야 하거나 특정 SDK 가 C++ 만 지원한다면 C++ 가 맞습니다. 이 비교는 '배포되는 작은 도구'라는 조건에서의 결론입니다.

수치의 조건과 한계는 앞의 측정 조건 절에 적어 두었습니다. 한 번의 측정 기록이고 원자료·중앙값이 없으므로, 이 글의 결론은 이 도구를 어떤 언어로 둘지에 대한 것이지 언어 일반의 성능 순위가 아닙니다.