TECH 으로 돌아가기
TECH HACKER NEWS 오늘 7분 읽기 28 READS

Bun 컴파일은 왜 이렇게 오래 걸릴까? 빌드 타임라인을 직접 그려본 개발자 이야기

Bun 컴파일은 왜 이렇게 오래 걸릴까? 빌드 타임라인을 직접 그려본 개발자 이야기
SOURCE IMAGE · HACKER NEWS
Bun 컴파일은 왜 이렇게 오래 걸릴까? 빌드 타임라인을 직접 그려본 개발자 이야기

Bun을 소스에서 빌드해 보셨나요?

Bun 아시죠? Zig 언어로 만든 초고속 자바스크립트 런타임이요. Node.js 대신 쓰는 분들이 요즘 꽤 많아졌는데요. 그런데 Bun을 직접 소스에서 빌드해 본 분은 드물 거예요. 해보면 알겠지만 정말 오래 걸리거든요. 한 개발자가 "도대체 어디서 시간을 잡아먹는 거지?"라는 궁금증을 참지 못하고, 빌드 과정을 눈으로 볼 수 있는 시각화 도구를 직접 만들었어요. 오늘은 이 이야기를 풀어볼게요.

왜 Bun 빌드는 이렇게 무거울까

Bun은 겉으로는 하나의 실행 파일이지만 속을 열어보면 세 덩어리가 섞여 있어요. 런타임 본체는 Zig로 되어 있고, 자바스크립트 엔진은 애플 WebKit의 JavaScriptCore(C++)를 가져다 쓰고, 그 둘을 이어주는 접착 코드가 또 C++로 있죠. 그러니까 Zig 컴파일러, C++ 컴파일러(clang), 그리고 이 모든 걸 하나로 합치는 링커가 차례로 돌아야 해요.

여기서 문제가 하나 있는데요. Zig는 C나 C++처럼 파일 하나하나를 따로 컴파일해서 나중에 합치는 방식이 아니에요. 프로젝트 전체를 하나의 컴파일 단위로 보고 한 번에 처리하거든요. 이게 뭐냐면, C++에서는 파일이 100개면 CPU 코어 16개에 나눠서 동시에 컴파일할 수 있는데, Zig는 그런 식으로 쪼개기가 어렵다는 뜻이에요. 그래서 코어가 아무리 많아도 Zig 부분은 사실상 한 줄로 오래 돌게 되죠. 거기에 LLVM 백엔드가 최적화까지 하면 몇 분이 그냥 지나가요.

빌드 프로파일러가 뭔가요

글쓴이가 만든 도구는 한마디로 '빌드 과정의 타임라인'을 그려주는 프로그램이에요. 이런 걸 빌드 프로파일러라고 부르는데요. 이게 뭐냐면, 빌드 중에 실행되는 컴파일러 명령 하나하나의 시작 시각과 끝난 시각을 기록해두고, 그걸 가로축이 시간인 그래프로 펼쳐 보여주는 거예요. 병원에서 환자 여러 명의 진료 시간을 한눈에 보는 일정표 같은 거죠.

이런 그래프를 보면 눈에 바로 들어오는 게 있어요. 첫째, 크리티컬 패스예요. 아무리 병렬로 돌려도 줄어들지 않는 가장 긴 의존 사슬이죠. A가 끝나야 B가 시작되고, B가 끝나야 C가 시작된다면 이 셋의 합이 빌드 시간의 하한선이 돼요. 둘째, 빈 구간이에요. 코어가 16개인데 그래프에 막대가 하나만 그려진 구간이 있다면, 나머지 15개 코어는 그 시간 동안 놀고 있다는 뜻이거든요. Bun의 Zig 컴파일 단계가 딱 이런 모양이에요. 셋째, 유독 뚱뚱한 막대예요. 특정 C++ 파일 하나가 다른 것들보다 열 배 오래 걸린다면, 그 파일이 템플릿을 과하게 쓰거나 헤더를 너무 많이 끌어오고 있다는 신호죠.

비슷한 도구들은 이미 있는데요

사실 이런 접근 자체가 새로운 건 아니에요. clang에는 -ftime-trace 옵션이 있어서 파일 하나를 컴파일할 때 파싱, 템플릿 인스턴스화, 최적화, 코드 생성에 각각 얼마나 걸렸는지 JSON으로 뽑아줘요. 이걸 크롬의 chrome://tracing이나 Perfetto에 넣으면 불꽃 그래프로 볼 수 있죠. Rust에는 cargo build --timings가 있어서 크레이트별 컴파일 시간을 HTML 리포트로 만들어주고, Bazel은 --profile 옵션으로 전체 빌드 프로파일을 남겨요. Gradle 쓰시는 분들은 빌드 스캔이 익숙하실 거고요.

그런데 Bun처럼 Zig와 C++와 링커가 뒤섞인 빌드는 이 도구들 중 어느 하나로도 전체 그림이 안 나와요. -ftime-trace는 C++ 파일 안쪽만 보여주고, Zig는 자기만의 빌드 시스템을 쓰니까요. 그래서 글쓴이는 빌드 시스템이 실행하는 각 명령을 바깥에서 감싸 시간을 재고, 그걸 하나의 타임라인으로 합치는 쪽을 택한 거예요. 개별 도구가 각자 잘하는 걸 놔두고 그 위에 한 층을 더 얹은 셈이죠.

한국 개발자에게 주는 시사점

당장 Bun을 빌드할 일은 없더라도, 이 접근법은 어느 팀에나 써먹을 수 있어요. CI에서 빌드가 20분 걸리는데 아무도 왜 그런지 모르는 상황, 한 번쯤 겪어보셨죠? 대부분은 감으로 "캐시를 켜자", "러너를 큰 걸로 바꾸자" 하고 넘어가는데, 실제로 타임라인을 그려보면 코어 절반이 놀고 있거나 파일 하나가 전체를 붙잡고 있는 경우가 정말 많거든요.

지금 쓰는 언어에 맞는 도구부터 켜보세요. C++이면 -ftime-trace, Rust면 --timings, Android면 Gradle 빌드 스캔이요. 그리고 여러 도구가 섞인 빌드라면 글쓴이처럼 명령 실행 시각을 기록하는 얇은 래퍼를 직접 만드는 것도 몇 시간이면 충분해요. 측정하지 않으면 최적화도 없다는 말, 빌드 시간에도 그대로 적용돼요.

정리하며

빌드가 느린 이유는 추측이 아니라 타임라인으로 확인해야 하고, 그걸 그려주는 도구는 생각보다 만들기 쉽다는 이야기였어요.

여러분 팀의 빌드는 몇 분 걸리나요? 그 시간이 어디로 가는지 실제로 측정해 본 적 있으신가요? 각자의 빌드 시간 줄이기 경험을 댓글로 나눠주세요.


🔗 출처: Hacker News

SOURCE · HACKER NEWS
원문 전체 보기 → https://lalitm.com/post/buildprof/
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기
처리 중...