GN⁺ 3달전 | parent | ★ favorite | on: Rust는 C보다 빠를까?(steveklabnik.com)
Hacker News 의견들
  • 요약하자면, 최대 속도는 거의 같지만, 실제 코드에서는 차이가 큼
    특히 멀티스레딩이 큰 변수임. Rust는 스레드를 쓰든 안 쓰든 모든 전역 변수가 스레드 안전해야 하고, 빌림 검사기(borrow checker)가 메모리 접근을 공유 또는 변경 중 하나로 제한함
    그래서 Rust에서는 멀티스레드 코드 작성이 거의 기본처럼 되어 있음. 반면 C에서는 스레드 생성 자체가 플랫폼 호환성 문제나 디버깅 리스크 때문에 부담이 큼

    • 솔직히 말하면, 이런 차이는 주로 표준 라이브러리의 편의성 차이 때문이라고 생각함
      C에서 스레드 빌드가 어렵진 않지만 Rust의 std::thread::spawn(move || { ... });보다는 번거로움
      메모리 안전성보다는 언어의 동시성 모델이 더 큰 영향을 줌. Go는 메모리 안전하지 않아도 go f()로 쉽게 병렬화함
      개인적으로는 Go에서 heisenbug를 더 자주 봤음
    • 멀티스레딩 외에도 Rust의 타입 시스템이 더 많은 정보를 제공해서 최적화 여지가 있을지 궁금함
    • 사실 #pragma omp for 한 줄이면 C에서도 간단히 병렬화할 수 있음
    • Linux에서 멀티스레딩하려면 왜 TBB 링크가 필요한지 아직도 혼란스러움. 기본 포함되어야 한다고 생각함
    • 스레드를 마구 추가하면 에너지 사용량경쟁 상태는 어떻게 되는지도 고려해야 함
  • Rust의 traits 덕분에 더 빠르고 유연한 추상화를 만들 수 있음
    C에서는 매크로나 함수 포인터로 흉내낼 수 있지만, Rust에서는 호출자가 동적 디스패치정적 디스패치를 선택할 수 있음
    임베디드 환경에서는 함수 포인터가 캐시를 망치고 성능을 깎는데, Rust traits는 인라인 최적화가 가능해서 훨씬 효율적임

    • ELF 해킹도 좋아하지만, 성능을 위해선 링커와 ABI, 바이너리 포맷을 잘 알아야 함
      Rust든 C든 결국 바이트 단위로 다뤄야 하며, 요즘은 바이너리 패칭 도구도 좋아져서 활용하기 쉬움
    • 물론 Rust에서도 함수 시그니처에 Box<dyn Trait>를 쓰면 호출자가 동적 디스패치를 강제당함
      impl Trait을 쓰면 호출자에게 선택권이 남음
    • 다만 traits를 많이 쓰면 빌드 타임 증가가 눈에 띔. 복잡한 trait일수록 컴파일이 느려짐
    • C식 접근은 아예 추상화를 피하는 것
  • 개인적으로 Rust, C, C++은 거의 같은 저수준 언어 계열이라 성능 차이는 미미하다고 봄
    Rust의 엄격한 aliasing 규칙은 최적화에 유리하고, C/C++의 UB(정의되지 않은 동작) 은 성능을 위해 존재함
    또 Rust와 C++의 제네릭은 C보다 훨씬 강력해서, 예를 들어 qsort() 대신 템플릿 기반 정렬은 인라인 최적화가 쉬움

    • C++의 템플릿은 여전히 Rust보다 표현력이 강하지만 점점 격차가 줄고 있음
    • 사실 이건 언어보다는 표준 라이브러리 설계 문제임. C에서도 직접 인라인 가능한 정렬 함수를 만들 수 있음
    • Rust의 정수 오버플로우 처리는 플랫폼 기본 동작을 따르므로, 최적화에 따라 결과가 달라질 수 있음
    • 언어는 단지 행동을 기술하는 수단일 뿐, 실제 속도는 컴파일러와 런타임 환경에 달려 있음
    • 세 언어의 성능 차이는 결국 노력 대비 효율의 문제임. C는 빠르지만 개발 비용이 크고, Rust는 그 중간쯤임
  • 이런 언어 간 속도 논쟁은 대부분 무의미하다고 생각함
    언어 자체보다 컴파일러 구현이 성능을 좌우함

    • 그래도 언어 설계는 최적화 가능성에 큰 영향을 줌. ‘충분히 똑똑한 컴파일러’는 아직 신화에 불과함
  • Rust, C, C++은 모두 낮은 수준의 언어지만, “빠르다”는 말의 정의가 중요함
    전문가가 최적화한 코드의 최고 속도를 말하는 건지, 아니면 평균적인 개발자가 예산 내에서 빠른 코드를 짤 확률을 말하는 건지 다름

    • 실제로는 컴파일러의 최적화 능력이 핵심임. Rust의 메모리 의미론이 더 풍부해서 컴파일러가 최적화 정보를 더 얻을 수 있음
      하지만 수작업 최적화를 하면 언어 차이는 거의 사라짐
      다만 Rust는 빠른 코드 작성이 더 쉬운 언어라는 점에서 약간의 우위가 있음
    • 대부분 사람들은 “평균적인 개발자가 빠른 코드를 짤 수 있는 언어”라는 정의를 씀
    • 언어 설계자는 ‘이 언어의 전형적인 코드가 얼마나 빠를까’ 를 염두에 두므로, 이 질문은 의미 있다고 생각함
  • Rust의 장점은 멀티스레딩스택 할당이라고 생각했음
    소유권 모델 덕분에 C/C++보다 스택에 더 많은 걸 올릴 수 있어 malloc/free 오버헤드를 줄임

    • 맞음, 하지만 이번 논의는 그런 구체적 차이보다 언어 설계 관점의 개념적 비교에 초점을 두었음
      이런 주제는 감정적으로 논쟁이 많아서, 구체적 수치보다는 사고방식의 차이를 다루고 싶었음
  • 언어의 “속도”를 논할 때는 두 가지를 봐야 함

    1. 언어가 프로그램에 어떤 비용을 주입하는가
    2. 언어가 어떤 최적화를 가능하게 하는가
      Rust와 C는 런타임 체크가 거의 없어서 Python이나 JS보다 빠름
      다만 Rust는 aliasing 정보를 더 잘 전달해 최적화 여지가 있음
      디버그 모드에서는 Ruby만큼 느리지만, 릴리스 모드에서는 C 수준의 속도를 냄
    • 이 관점이 마음에 듦. C++의 zero-cost abstraction 개념과도 연결됨
    • JS도 많이 최적화되어 있지만, 여전히 Rust/C보다 약간 느림
    • 또 하나의 질문은 “평범한 개발자가 쓸 때 얼마나 빠른가”임. 언어가 기본적으로 빠른 코드를 유도하는지가 중요함
  • C보다 C++이나 Rust가 컴파일 타임 기능이 풍부해서 빠른 코드를 쓰기 쉬움
    예를 들어 이 코드는 C에서는 거의 불가능함

  • 어셈블리는 C 표준의 일부가 아니므로 Rust와 직접 비교하기 어렵고, Rust는 오히려 GCC 프로젝트에 더 가까운 성격임

  • 어떤 언어가 “빠르다”는 건 결국 구현과 맥락에 따라 달라짐
    언어 자체의 속도보다, 컴파일러와 하드웨어의 조합이 더 큰 영향을 미침

평균적으로 어떤 언어가 가장 빠를지는 모르겠지만 산포는 c++이 제일 클 것 같습니다.