1995년에 고등학교를 졸업하면서 Intel 486에서 "Borland Pascal 버전 Turbo Vision for DOS"를 재컴파일하던 속도와 맞먹을 정도로 이젠 정말 빠른 컴파일 속도를 경험함
Turbo Vision은 TUI 윈도우 프레임워크로, Borland Pascal과 C++ IDE 개발에 사용함
JetBrains IDE를 1000MB 대신 10MB로 구현한 캐릭터 모드라 할 만함 Turbo Vision 위키피디아
LLVM은 일종의 함정임
부트스트랩이 정말 빠르고 온갖 최적화 패스와 다양한 플랫폼 지원을 공짜로 얻지만, 마지막 최적화 단계나 링킹 단계의 성능을 세밀하게 조정하는 능력을 잃게 됨
Cranelift가 Rust에서 곧 활성화될 것이라고 생각함
하지만 Rust가 초기에는 LLVM을 선택했기에 지금의 위상을 갖게 된 것임
Go는 코드 생성과 링크를 외부에 맡기지 않고 자체 관리하기로 예전부터 결정했고, 그 선택 덕을 톡톡히 보고 있음
LLVM이 함정이라는 주장에 동의하기 어렵고, Rust가 오히려 좋은 사례임
실제로 LLVM으로 코드 생성하는 부분은 컴파일러에서 매우 적은 부분을 차지하고, 대체하려면 codegen_cranelift나 codegen_gcc 등으로 바꿀 수도 있음
SIMD 벤더 인트린식 의존성이 ‘락인’ 문제이긴 하나, 이는 언어 구조의 문제임
대부분의 언어는 LLVM 백엔드로 시작하는 게 합리적임
C/C++과 유사한 언어엔 LLVM 기본 파이프라인만으로도 최적화가 잘 되지만, 특징이 다른 언어일수록 직접 최적화 파이프라인을 작성함
Go처럼 초기부터 자체 백엔드를 통합해온 사례가 성공적으로 보이긴 하지만, 특별한 차별화 요소가 되는 건 아니고, 직접 구현에는 꽤 많은 기회비용이 따름
Go와 Ocaml 컴파일러는 정말 빠름
처음부터 자체 라이브러리를 제대로 구축했고, 이제는 속도 측면에서 손해를 볼 일이 없음
앞으로 1분 이상 걸리는 컴파일 환경에서는 일하고 싶지 않음
프로젝트마다 ‘dev’ 전용 컴파일러를 두고, 최종 빌드에만 llvm 같은 무거운 걸 사용했으면 함
LLVM 기반 언어가 C++ 대체를 목표로 한다면, 여전히 C++에 의존하게 됨
언어는 자기 자신만으로 부트스트랩해야 함
초기에는 편리한 도구들이 있지만, 단지 시간절약 수단이고 필수품은 아님
Go 팀이 내린 선택에 완전히 공감함
Cranelift의 지속적인 성장을 바람
지금의 LLVM은 CPU 벤더별로 포크가 쏟아져나와, 각각이 비공개 패키지에 CPU별 개선이 묶여 있음
다른 언어 프론트엔드를 쓰거나 컴파일러 버그가 나오면 매우 험난한 상황임
언어들이 자유롭게 다른 백엔드로 이동할 수 있는데 어떻게 함정일 수 있냐는 의문 제기함
컴파일 속도가 개발을 방해한다면, 왜 인터프리터를 만들지 않느냐는 의문
실행 속도와 컴파일 속도가 필연적으로 독립적 관계임
인터프리터를 쓰면 코드 인스트루먼트나 런타임 제어 등 추가적인 개발 도구도 쉽게 만들 수 있음
최적화된 RELEASE 바이너리만 디버깅해야 하는 극소수 케이스가 있지만, 대부분의 경우에는 인터프리터나 DEBUG 빌드로 충분함
Rust는 안전성, 성능, 사용성 순이고 Zig는 성능, 사용성, 안전성 순으로 분류된다고 들음
이런 관점에서 빌드 속도 개선은 설득력이 있지만, 인터프리터는 사용성이 우선일 때 더 적합한 대안임
Julia의 접근이 마음에 듦
풀 인터랙티브 환경에서 인터프리터가 실은 코드를 컴파일 후 바로 실행함
SBCL 같은 Common Lisp 환경도 마찬가지임
실행 속도와 컴파일 속도는 극단적으로 보면 독립적임
그 사이 "타협 가능한 영역"이 있어서, 실행 파일의 성능 손실 없이 컴파일러를 더 빠르게 만들 수도 있음
게임 분야는 특별한 경우가 아니라고 주장함
지금까지 최고의 컴파일러 속도는 TCC (Fabrice Bellard 작품)임
멀티스레드나 복잡한 최적화 없이도 압도적으로 빠름
릴리즈에는 Clang을 쓰지만 TCC의 코드 생성 성능도 나쁘지 않음
Delphi가 훨씬 더 표현력 있고 안전하면서도 매우 빠른 컴파일 속도를 제공한다고 생각함
Go 컴파일러도 꽤 빠름
DMD가 C와 D 모두 컴파일할 수 있으면서도 "골드 스탠다드"라 생각했음
TCC가 C23을 지원해줬으면 좋겠다고 바람을 밝힘
한 가지가 "진짜 골드 스탠다드"란 건 없음
vlang도 재컴파일이 몇 초면 끝날 정도로 빠르고, Go의 컴파일러 역시 굉장히 빠름
빌드 캐싱 등 재컴파일 자체를 아예 피하는 기술도 있기에, 누구만의 전유물이 아님
zig로 앱을 빌드하는 과정에서 인크리멘탈 빌드에 만족도가 컸음
SQLite, luau 등 다양한 라이브러리를 쓰는 단일 정적 바이너리를 Go만큼 빨리 빌드 가능함
다만 아직까지 self-hosted 컴파일러에는 꽤 버그가 남아 있음
예로 SQLite는 llvm을 써야 하며, 관련 이슈는 여기에서 확인 가능함
Zig가 Bazel, Buck2 같은 빌드 시스템과 잘 연계될 수 있는지 궁금함
Zig는 빌드 스크립트가 튜링 완전해서, 이런 시스템에서는 캐싱과 빌드 자동화가 쉽지 않을까 걱정임
Rust에서 build.rs 없이 쓸 수 있는 라이브러리가 더 선호되는 이유와 같음
Zig 라이브러리도 커스텀 빌드가 많은지 궁금함
Zig의 빌드 스크립트는 완전히 옵션임
build.zig 없이도 개별 소스 파일을 바로 빌드/실행 가능함
GCC나 Clang이 들어가는 워크플로우 어디에나 Zig를 연동할 수 있음
참고로 Zig는 C 컴파일러 대체품으로도 동작함 관련 글
Zig의 컴파일 및 코드 생성이 TPDE와 비교해 어떤지 궁금함
LLVM -O0 보다 10~20배 빠르다고 하지만 한계는 있는 듯함
Zig의 전략은 대담하다고 봄
하지만 아직까지 LLVM 백엔드를 쓰는 게 맞는지 궁금함
LLVM이 컴파일 속도와 플랫폼 지원 면에선 경쟁력이 있지만, 최적 기계어 생산에서는 따라올 곳이 없음
Release 빌드에만 LLVM 백엔드를 쓰고, debug 빌드는 지원되는 플랫폼에 한해 self-hosted 방식이 기본임
디버그 빌드는 실제 테스트 과정에서 여러 번 반복 빌드하기 때문에 이 방식이 더 합리적임
컴파일러 성능 집착에는 공감 못함
결국 최적화 패스(인라이닝, dead code 제거 등)와 컴파일 시간 중 하나를 선택하는 트레이드 오프임
최적화 없는 컴파일러는 선형적으로 빨라질 뿐이며, 그 이상 최적화를 하려면 언제나 시간 소모가 커질 수밖에 없음
"뛰어난 어셈블리 출력"은 실제로 중요한 이슈는 아님
Proebsting's Law에 따르면 컴파일러 기술 발전이 기계 성능 상승보다 훨씬 느림
쉽고 빠른 최적화만으로도 실용적으로 충분하다는 결론임
LLVM이 절대적 최적화도, 컴파일 속도와 비교했을 때 금방 한계에 부딪히게 됨
JNI로 C 라이브러리를 감싸는 Java 라이브러리를 만드는 데, 플랫폼별 다이나믹 라이브러리 빌드가 너무 번거로워서 zig로 멀티 플랫폼 빌드를 고민 중임
단순 shim이라면 최신 Java에서 Panama와 jextract 활용이 더 나을 것임
Zig는 헤더, libc 소스, 자체 LLVM을 모두 내장하며 크로스 컴파일이 정말 쉬움
정말 아무것도 신경 안 써도 될 정도임
Ghostty가 지금 self-hosted x86_64 백엔드로 빌드가 안 되는 이유를 궁금해함
Hacker News 의견
1995년에 고등학교를 졸업하면서 Intel 486에서 "Borland Pascal 버전 Turbo Vision for DOS"를 재컴파일하던 속도와 맞먹을 정도로 이젠 정말 빠른 컴파일 속도를 경험함
Turbo Vision은 TUI 윈도우 프레임워크로, Borland Pascal과 C++ IDE 개발에 사용함
JetBrains IDE를 1000MB 대신 10MB로 구현한 캐릭터 모드라 할 만함
Turbo Vision 위키피디아
LLVM은 일종의 함정임
부트스트랩이 정말 빠르고 온갖 최적화 패스와 다양한 플랫폼 지원을 공짜로 얻지만, 마지막 최적화 단계나 링킹 단계의 성능을 세밀하게 조정하는 능력을 잃게 됨
Cranelift가 Rust에서 곧 활성화될 것이라고 생각함
하지만 Rust가 초기에는 LLVM을 선택했기에 지금의 위상을 갖게 된 것임
Go는 코드 생성과 링크를 외부에 맡기지 않고 자체 관리하기로 예전부터 결정했고, 그 선택 덕을 톡톡히 보고 있음
LLVM이 함정이라는 주장에 동의하기 어렵고, Rust가 오히려 좋은 사례임
실제로 LLVM으로 코드 생성하는 부분은 컴파일러에서 매우 적은 부분을 차지하고, 대체하려면 codegen_cranelift나 codegen_gcc 등으로 바꿀 수도 있음
SIMD 벤더 인트린식 의존성이 ‘락인’ 문제이긴 하나, 이는 언어 구조의 문제임
대부분의 언어는 LLVM 백엔드로 시작하는 게 합리적임
C/C++과 유사한 언어엔 LLVM 기본 파이프라인만으로도 최적화가 잘 되지만, 특징이 다른 언어일수록 직접 최적화 파이프라인을 작성함
Go처럼 초기부터 자체 백엔드를 통합해온 사례가 성공적으로 보이긴 하지만, 특별한 차별화 요소가 되는 건 아니고, 직접 구현에는 꽤 많은 기회비용이 따름
Go와 Ocaml 컴파일러는 정말 빠름
처음부터 자체 라이브러리를 제대로 구축했고, 이제는 속도 측면에서 손해를 볼 일이 없음
앞으로 1분 이상 걸리는 컴파일 환경에서는 일하고 싶지 않음
프로젝트마다 ‘dev’ 전용 컴파일러를 두고, 최종 빌드에만 llvm 같은 무거운 걸 사용했으면 함
LLVM 기반 언어가 C++ 대체를 목표로 한다면, 여전히 C++에 의존하게 됨
언어는 자기 자신만으로 부트스트랩해야 함
초기에는 편리한 도구들이 있지만, 단지 시간절약 수단이고 필수품은 아님
Go 팀이 내린 선택에 완전히 공감함
Cranelift의 지속적인 성장을 바람
지금의 LLVM은 CPU 벤더별로 포크가 쏟아져나와, 각각이 비공개 패키지에 CPU별 개선이 묶여 있음
다른 언어 프론트엔드를 쓰거나 컴파일러 버그가 나오면 매우 험난한 상황임
언어들이 자유롭게 다른 백엔드로 이동할 수 있는데 어떻게 함정일 수 있냐는 의문 제기함
컴파일 속도가 개발을 방해한다면, 왜 인터프리터를 만들지 않느냐는 의문
실행 속도와 컴파일 속도가 필연적으로 독립적 관계임
인터프리터를 쓰면 코드 인스트루먼트나 런타임 제어 등 추가적인 개발 도구도 쉽게 만들 수 있음
최적화된 RELEASE 바이너리만 디버깅해야 하는 극소수 케이스가 있지만, 대부분의 경우에는 인터프리터나 DEBUG 빌드로 충분함
Rust는 안전성, 성능, 사용성 순이고 Zig는 성능, 사용성, 안전성 순으로 분류된다고 들음
이런 관점에서 빌드 속도 개선은 설득력이 있지만, 인터프리터는 사용성이 우선일 때 더 적합한 대안임
Julia의 접근이 마음에 듦
풀 인터랙티브 환경에서 인터프리터가 실은 코드를 컴파일 후 바로 실행함
SBCL 같은 Common Lisp 환경도 마찬가지임
실행 속도와 컴파일 속도는 극단적으로 보면 독립적임
그 사이 "타협 가능한 영역"이 있어서, 실행 파일의 성능 손실 없이 컴파일러를 더 빠르게 만들 수도 있음
게임 분야는 특별한 경우가 아니라고 주장함
지금까지 최고의 컴파일러 속도는 TCC (Fabrice Bellard 작품)임
멀티스레드나 복잡한 최적화 없이도 압도적으로 빠름
릴리즈에는 Clang을 쓰지만 TCC의 코드 생성 성능도 나쁘지 않음
Delphi가 훨씬 더 표현력 있고 안전하면서도 매우 빠른 컴파일 속도를 제공한다고 생각함
Go 컴파일러도 꽤 빠름
DMD가 C와 D 모두 컴파일할 수 있으면서도 "골드 스탠다드"라 생각했음
TCC가 C23을 지원해줬으면 좋겠다고 바람을 밝힘
한 가지가 "진짜 골드 스탠다드"란 건 없음
vlang도 재컴파일이 몇 초면 끝날 정도로 빠르고, Go의 컴파일러 역시 굉장히 빠름
빌드 캐싱 등 재컴파일 자체를 아예 피하는 기술도 있기에, 누구만의 전유물이 아님
zig로 앱을 빌드하는 과정에서 인크리멘탈 빌드에 만족도가 컸음
SQLite, luau 등 다양한 라이브러리를 쓰는 단일 정적 바이너리를 Go만큼 빨리 빌드 가능함
다만 아직까지 self-hosted 컴파일러에는 꽤 버그가 남아 있음
예로 SQLite는 llvm을 써야 하며, 관련 이슈는 여기에서 확인 가능함
Zig가 Bazel, Buck2 같은 빌드 시스템과 잘 연계될 수 있는지 궁금함
Zig는 빌드 스크립트가 튜링 완전해서, 이런 시스템에서는 캐싱과 빌드 자동화가 쉽지 않을까 걱정임
Rust에서 build.rs 없이 쓸 수 있는 라이브러리가 더 선호되는 이유와 같음
Zig 라이브러리도 커스텀 빌드가 많은지 궁금함
Zig의 빌드 스크립트는 완전히 옵션임
build.zig 없이도 개별 소스 파일을 바로 빌드/실행 가능함
GCC나 Clang이 들어가는 워크플로우 어디에나 Zig를 연동할 수 있음
참고로 Zig는 C 컴파일러 대체품으로도 동작함
관련 글
Bazel과 Zig 연동 예시로 rules_zig 소개
실제 프로젝트 ZML도 이를 활용함
ZML 프로젝트
Zig의 컴파일 및 코드 생성이 TPDE와 비교해 어떤지 궁금함
LLVM -O0 보다 10~20배 빠르다고 하지만 한계는 있는 듯함
Zig의 전략은 대담하다고 봄
하지만 아직까지 LLVM 백엔드를 쓰는 게 맞는지 궁금함
LLVM이 컴파일 속도와 플랫폼 지원 면에선 경쟁력이 있지만, 최적 기계어 생산에서는 따라올 곳이 없음
Release 빌드에만 LLVM 백엔드를 쓰고, debug 빌드는 지원되는 플랫폼에 한해 self-hosted 방식이 기본임
디버그 빌드는 실제 테스트 과정에서 여러 번 반복 빌드하기 때문에 이 방식이 더 합리적임
컴파일러 성능 집착에는 공감 못함
결국 최적화 패스(인라이닝, dead code 제거 등)와 컴파일 시간 중 하나를 선택하는 트레이드 오프임
최적화 없는 컴파일러는 선형적으로 빨라질 뿐이며, 그 이상 최적화를 하려면 언제나 시간 소모가 커질 수밖에 없음
"뛰어난 어셈블리 출력"은 실제로 중요한 이슈는 아님
Proebsting's Law에 따르면 컴파일러 기술 발전이 기계 성능 상승보다 훨씬 느림
쉽고 빠른 최적화만으로도 실용적으로 충분하다는 결론임
LLVM이 절대적 최적화도, 컴파일 속도와 비교했을 때 금방 한계에 부딪히게 됨
JNI로 C 라이브러리를 감싸는 Java 라이브러리를 만드는 데, 플랫폼별 다이나믹 라이브러리 빌드가 너무 번거로워서 zig로 멀티 플랫폼 빌드를 고민 중임
단순 shim이라면 최신 Java에서 Panama와 jextract 활용이 더 나을 것임
Zig는 헤더, libc 소스, 자체 LLVM을 모두 내장하며 크로스 컴파일이 정말 쉬움
정말 아무것도 신경 안 써도 될 정도임
Ghostty가 지금 self-hosted x86_64 백엔드로 빌드가 안 되는 이유를 궁금해함
Zig 컴파일러가 버그로 크래시 남
아직 신기술이라 복잡하지만 곧 해결될 것임
대부분 Ghostty 유저가 aarch64 플랫폼임