11P by GN⁺ 19시간전 | ★ favorite | 댓글 5개
  • 러스트와 C의 성능 비교는 “모든 조건이 동일하다”는 전제의 정의에 따라 달라지는 복잡한 문제임
  • 인라인 어셈블리의 경우 두 언어 모두 동일한 어셈블리 코드를 생성할 수 있어, 언어 자체의 속도 차이는 없음
  • 구조체 메모리 배치에서는 러스트가 필드 재정렬을 통해 더 작은 크기를 가질 수 있으나, #[repr(C)] 속성으로 C와 동일한 레이아웃도 가능함
  • 런타임 검사와 개발자 행태 차이로 인해 실제 프로젝트에서는 코드 구조와 성능이 달라질 수 있음
  • 결론적으로 언어 자체의 한계로 인한 성능 차이는 없으며, 프로젝트와 개발자 요인에 따라 결과가 달라짐

문제 제기와 전제의 모호함

  • Reddit에서 제기된 “같은 조건이라면 Rust가 C보다 빠를 수 있는가” 라는 질문이 출발점
  • “모든 조건이 동일함” 이라는 표현 자체가 언어 비교에서 매우 정의하기 어려운 개념임
  • 성능 비교는 언어 차이뿐 아니라 코드 형태, 개발 판단, 컴파일러 최적화에 따라 달라짐

인라인 어셈블리 비교

  • 러스트는 언어 차원에서 인라인 어셈블리를 지원하며, C는 컴파일러 확장 기능으로 이를 구현
    • 두 언어 모두 rdtsc 명령을 사용하는 동일한 예제를 작성할 수 있음
    • rustc 1.87.0clang 20.1.0에서 생성된 어셈블리는 완전히 동일한 형태로 출력됨
  • 이 사례는 언어의 성능 차이를 보여주지는 않지만, 러스트가 C와 동일한 수준의 저수준 제어를 수행할 수 있음을 입증

구조체 레이아웃 차이

  • 러스트 구조체는 필드 재정렬을 통해 메모리 사용을 최적화할 수 있음
    • 예시에서 러스트 구조체는 16바이트, 동일한 C 구조체는 24바이트로 계산됨
  • C에서는 필드 순서를 수동으로 변경해야 동일한 크기를 얻을 수 있음
  • 러스트에서 #[repr(C)] 속성을 사용하면 C와 동일한 메모리 레이아웃을 강제할 수 있음

사회적·개발자 요인

  • 러스트의 안전성 검사 덕분에 개발자가 더 공격적인 최적화를 시도할 수 있는 사례가 있음
    • Mozilla의 Stylo 프로젝트에서는 C++로 두 차례 병렬화 시도가 실패했으나, 러스트로는 성공적으로 구현됨
  • 동일한 프로젝트라도 언어와 개발자 숙련도에 따라 결과 코드의 성능과 안정성이 달라질 수 있음
  • 초급 개발자와 전문가, 언어 숙련도에 따라 “같은 작업”의 결과가 다르므로, 단순 비교는 어려움

컴파일 타임과 런타임 검사

  • 러스트의 많은 안전성 검사는 컴파일 타임에 수행되지만, 일부는 런타임 검사로 남음
    • 예를 들어 array[0] 접근 시 러스트는 경계 검사를 수행하지만, C는 수행하지 않음
    • 러스트에서 get_unchecked()를 사용하면 C와 동일한 동작을 얻을 수 있음
  • 컴파일러가 안전성을 증명할 수 있는 경우, 두 언어 모두 검사를 최적화로 제거할 수 있음
  • 이러한 차이는 코드 작성 방식에 영향을 주며, 결과적으로 성능 차이를 유발할 수 있음

결론

  • C가 “가장 빠른 언어”라고 가정하더라도, 러스트가 동일한 수준의 성능을 낼 수 없는 이유는 없음
  • 언어 자체의 한계보다는 프로젝트 특성, 개발자 역량, 시간 제약 등 외부 변수가 성능 차이를 결정
  • 따라서 “러스트가 C보다 빠른가?”라는 질문은 언어 비교보다는 엔지니어링 맥락의 문제로 해석됨

Rust는 C보다는 C++의 대체제가 될거라고 봄. C는 컴파일러가 만들어낼 코드를 짐작할 수 있는 사실상 유일한(어쩌면 최후의) 언어…

쓰다보니 AI요약체 ㅠㅠ

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 프로젝트에 더 가까운 성격임

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

그건 컴파일러 역량에 달림.

같은 코드를 어셈블링 해보면 나오겠죠.

ffmpeg아조씨들은 rust가 c보다 빠른건 아니다 생각하는것 같긴하네요 ㅋㅋ https://www.memorysafety.org/blog/rav1d-perf-bounty/