13 điểm bởi GN⁺ 2026-01-15 | 6 bình luận | Chia sẻ qua WhatsApp
  • So sánh hiệu năng giữa Rust và C là một vấn đề phức tạp, phụ thuộc vào cách định nghĩa giả định “mọi điều kiện đều như nhau”
  • Với assembly nội tuyến, cả hai ngôn ngữ đều có thể tạo ra cùng một mã assembly, nên không có khác biệt về tốc độ do bản thân ngôn ngữ
  • bố cục bộ nhớ của struct, Rust có thể đạt kích thước nhỏ hơn nhờ sắp xếp lại các field, nhưng cũng có thể dùng thuộc tính #[repr(C)] để có bố cục giống hệt C
  • Do khác biệt về kiểm tra lúc chạy và cách lập trình viên triển khai mã, cấu trúc mã và hiệu năng trong dự án thực tế có thể thay đổi
  • Kết luận là không có khác biệt hiệu năng do giới hạn nội tại của ngôn ngữ, mà kết quả phụ thuộc vào dự án và yếu tố con người

Nêu vấn đề và sự mơ hồ của giả định

  • Câu hỏi “nếu cùng điều kiện thì Rust có thể nhanh hơn C không” được nêu ra trên Reddit là điểm khởi đầu
  • Cách diễn đạt “mọi điều kiện đều như nhau” bản thân nó là một khái niệm rất khó xác định khi so sánh ngôn ngữ
  • So sánh hiệu năng không chỉ thay đổi theo khác biệt ngôn ngữ mà còn theo dạng mã, quyết định của lập trình viên và tối ưu hóa của trình biên dịch

So sánh assembly nội tuyến

  • Rust hỗ trợ assembly nội tuyến ở cấp độ ngôn ngữ, còn C triển khai điều này qua phần mở rộng của trình biên dịch
    • Cả hai ngôn ngữ đều có thể viết cùng một ví dụ dùng lệnh rdtsc
    • Assembly được tạo ra từ rustc 1.87.0clang 20.1.0 có hình thức hoàn toàn giống nhau
  • Trường hợp này không chứng minh chênh lệch hiệu năng giữa các ngôn ngữ, nhưng cho thấy Rust có thể thực hiện mức kiểm soát cấp thấp tương đương C

Khác biệt về bố cục struct

  • Struct trong Rust có thể tối ưu việc sử dụng bộ nhớ bằng cách sắp xếp lại các field
    • Trong ví dụ, struct của Rust có kích thước 16 byte, còn struct tương ứng trong C là 24 byte
  • Trong C, cần tự thay đổi thứ tự field thì mới đạt được cùng kích thước
  • Nếu dùng thuộc tính #[repr(C)] trong Rust, có thể ép bố cục bộ nhớ giống hệt C

Yếu tố xã hội và con người

  • Nhờ các kiểm tra an toàn của Rust, có những trường hợp lập trình viên dám thử các tối ưu hóa mạnh tay hơn
    • Trong dự án Stylo của Mozilla, hai lần thử song song hóa bằng C++ đều thất bại, nhưng với Rust thì đã triển khai thành công
  • Ngay cả trong cùng một dự án, hiệu năng và độ ổn định của mã kết quả cũng có thể khác nhau tùy ngôn ngữ và trình độ của lập trình viên
  • Vì kết quả của “cùng một công việc” khác nhau giữa người mới và chuyên gia, cũng như theo mức độ thành thạo ngôn ngữ, nên rất khó so sánh đơn giản

Kiểm tra thời gian biên dịch và thời gian chạy

  • Nhiều kiểm tra an toàn của Rust được thực hiện khi biên dịch, nhưng một phần vẫn còn là kiểm tra lúc chạy
    • Ví dụ, khi truy cập array[0], Rust thực hiện kiểm tra biên, còn C thì không
    • Nếu dùng get_unchecked() trong Rust thì có thể đạt hành vi giống C
  • Khi trình biên dịch có thể chứng minh được tính an toàn, cả hai ngôn ngữ đều có thể loại bỏ các kiểm tra nhờ tối ưu hóa
  • Những khác biệt này ảnh hưởng đến cách viết mã và cuối cùng có thể dẫn tới khác biệt hiệu năng

Kết luận

  • Ngay cả khi giả định C là “ngôn ngữ nhanh nhất”, không có lý do gì Rust lại không thể đạt mức hiệu năng tương đương
  • Thứ quyết định khác biệt hiệu năng không phải giới hạn nội tại của ngôn ngữ mà là đặc thù dự án, năng lực lập trình viên, ràng buộc thời gian và các biến số bên ngoài khác
  • Vì vậy, câu hỏi “Rust có nhanh hơn C không?” nên được hiểu là vấn đề của bối cảnh kỹ thuật phần mềm hơn là so sánh ngôn ngữ

6 bình luận

 
GN⁺ 2026-01-15
Ý kiến trên Hacker News
  • Tóm lại, tốc độ tối đa gần như ngang nhau, nhưng trong code thực tế thì khác biệt khá lớn
    Đặc biệt đa luồng là biến số rất lớn. Rust yêu cầu mọi biến toàn cục phải an toàn luồng dù có dùng luồng hay không, và borrow checker giới hạn việc truy cập bộ nhớ vào một trong hai kiểu: chia sẻ hoặc thay đổi
    Vì vậy trong Rust, việc viết code đa luồng gần như là mặc định. Trong khi đó ở C, ngay cả việc tạo luồng cũng đã là gánh nặng do vấn đề tương thích nền tảng và rủi ro khi debug

    • Nói thật thì tôi nghĩ khác biệt này chủ yếu đến từ độ tiện của thư viện chuẩn
      Việc dựng luồng trong C không hẳn khó, nhưng vẫn rườm rà hơn Rust với std::thread::spawn(move || { ... });
      Tác động lớn hơn nằm ở mô hình đồng thời của ngôn ngữ hơn là độ an toàn bộ nhớ. Go dù không an toàn bộ nhớ vẫn có thể song song hóa dễ dàng bằng go f()
      Cá nhân tôi lại thấy heisenbug trong Go thường xuyên hơn
    • Ngoài đa luồng, tôi cũng tò mò liệu hệ thống kiểu của Rust có cung cấp thêm thông tin để tối ưu hóa tốt hơn không
    • Thực ra chỉ cần một dòng #pragma omp for là C cũng có thể song song hóa đơn giản
    • Tôi vẫn thấy khó hiểu vì sao để làm đa luồng trên Linux lại cần liên kết TBB. Theo tôi đáng lẽ nó phải được kèm sẵn theo mặc định
    • Nếu cứ thêm luồng bừa bãi thì cũng phải tính đến mức tiêu thụ năng lượngrace condition sẽ ra sao
  • Nhờ traits, Rust có thể tạo ra các lớp trừu tượng vừa nhanh vừa linh hoạt hơn
    Ở C có thể bắt chước bằng macro hoặc function pointer, nhưng trong Rust thì phía gọi có thể chọn dynamic dispatch hoặc static dispatch
    Trong môi trường nhúng, function pointer làm hỏng cache và giảm hiệu năng, còn Rust traits cho phép tối ưu inline nên hiệu quả hơn nhiều

    • Tôi cũng thích hack ELF, nhưng nếu muốn tối ưu hiệu năng thì phải hiểu rõ linker, ABI và định dạng nhị phân
      Dù là Rust hay C thì cuối cùng vẫn phải xử lý ở cấp byte, và dạo này các công cụ vá nhị phân cũng đã tốt hơn nhiều nên dễ tận dụng hơn
    • Tất nhiên trong Rust, nếu dùng Box<dyn Trait> trong chữ ký hàm thì phía gọi sẽ bị ép dùng dynamic dispatch
      Nếu dùng impl Trait thì phía gọi vẫn còn quyền lựa chọn
    • Tuy vậy, dùng traits nhiều thì thời gian build tăng thấy rõ. Trait càng phức tạp thì compile càng chậm
    • Cách tiếp cận kiểu C là tránh hẳn trừu tượng hóa
  • Cá nhân tôi thấy Rust, C và C++ gần như cùng thuộc một họ ngôn ngữ cấp thấp, nên chênh lệch hiệu năng là rất nhỏ
    Quy tắc aliasing nghiêm ngặt của Rust có lợi cho tối ưu hóa, còn UB (hành vi không xác định) trong C/C++ tồn tại để phục vụ hiệu năng
    Ngoài ra generic của Rust và C++ cũng mạnh hơn C rất nhiều, nên ví dụ sắp xếp dựa trên template sẽ dễ tối ưu inline hơn qsort()

    • Template của C++ vẫn giàu khả năng biểu đạt hơn Rust, nhưng khoảng cách đang dần thu hẹp
    • Thực ra đây là vấn đề thiết kế thư viện chuẩn hơn là vấn đề ngôn ngữ. Trong C cũng có thể tự viết hàm sắp xếp có thể inline trực tiếp
    • Cách Rust xử lý tràn số nguyên tuân theo hành vi mặc định của nền tảng, nên kết quả có thể thay đổi tùy tối ưu hóa
    • Ngôn ngữ chỉ là phương tiện mô tả hành vi, còn tốc độ thực tế phụ thuộc vào compiler và môi trường runtime
    • Khác biệt hiệu năng giữa ba ngôn ngữ cuối cùng là vấn đề hiệu quả so với công sức bỏ ra. C nhanh nhưng chi phí phát triển cao, còn Rust nằm đâu đó ở giữa
  • Tôi nghĩ những cuộc tranh cãi tốc độ giữa các ngôn ngữ phần lớn là vô nghĩa
    Thứ quyết định hiệu năng không phải bản thân ngôn ngữ mà là cách hiện thực compiler

    • Dù vậy, thiết kế ngôn ngữ vẫn ảnh hưởng lớn đến khả năng tối ưu hóa. Một compiler ‘đủ thông minh’ đến giờ vẫn chỉ là huyền thoại
  • Rust, C và C++ đều là ngôn ngữ cấp thấp, nhưng định nghĩa của “nhanh” mới là điều quan trọng
    Là đang nói đến tốc độ tối đa của code do chuyên gia tối ưu, hay là xác suất để một lập trình viên bình thường viết được code nhanh trong phạm vi ngân sách

    • Trên thực tế, khả năng tối ưu hóa của compiler mới là cốt lõi. Ngữ nghĩa bộ nhớ của Rust phong phú hơn nên compiler có thể lấy thêm thông tin để tối ưu
      Nhưng nếu tối ưu thủ công thì khác biệt giữa các ngôn ngữ gần như biến mất
      Dù vậy, Rust vẫn nhỉnh hơn một chút ở chỗ đây là ngôn ngữ giúp viết code nhanh hiệu quả dễ hơn
    • Hầu hết mọi người dùng định nghĩa kiểu “ngôn ngữ mà lập trình viên bình thường có thể viết code nhanh”
    • Nhà thiết kế ngôn ngữ thường nghĩ đến câu hỏi ‘code điển hình trong ngôn ngữ này sẽ nhanh đến mức nào?’, nên tôi thấy đây là một câu hỏi có ý nghĩa
  • Tôi từng nghĩ ưu điểm của Rust là đa luồngcấp phát trên stack
    Nhờ mô hình ownership, có thể đưa nhiều thứ lên stack hơn so với C/C++, từ đó giảm overhead của malloc/free

    • Đúng vậy, nhưng cuộc thảo luận này tập trung vào so sánh khái niệm dưới góc nhìn thiết kế ngôn ngữ hơn là những khác biệt cụ thể như thế
      Chủ đề kiểu này dễ gây tranh cãi cảm tính, nên tôi muốn bàn về sự khác biệt trong cách tư duy hơn là các con số cụ thể
  • Khi bàn về “tốc độ” của ngôn ngữ thì cần nhìn vào hai điểm

    1. ngôn ngữ đưa thêm chi phí gì vào chương trình
    2. ngôn ngữ cho phép những tối ưu hóa nào
      Rust và C hầu như không có runtime check nên nhanh hơn Python hay JS
      Tuy nhiên Rust truyền đạt thông tin aliasing tốt hơn nên có thêm dư địa tối ưu hóa
      Ở chế độ debug thì nó chậm ngang Ruby, nhưng ở chế độ release thì đạt tốc độ mức C
    • Tôi thích góc nhìn này. Nó cũng gắn với khái niệm zero-cost abstraction trong C++
    • JS cũng được tối ưu rất nhiều, nhưng vẫn chậm hơn Rust/C một chút
    • Còn một câu hỏi nữa là “nhanh đến mức nào khi lập trình viên bình thường sử dụng”. Điều quan trọng là ngôn ngữ có mặc định dẫn người ta đến code nhanh hay không
  • So với C, C++ hay Rust có nhiều tính năng thời điểm biên dịch hơn nên dễ viết code nhanh hơn
    Ví dụ đoạn code này gần như không thể làm được trong C

  • Assembly không phải là một phần của tiêu chuẩn C nên khó so sánh trực tiếp với Rust, và Rust thực ra có tính chất gần với dự án GCC hơn

  • Việc một ngôn ngữ có “nhanh” hay không cuối cùng vẫn phụ thuộc vào cách triển khai và bối cảnh
    So với tốc độ của bản thân ngôn ngữ, sự kết hợp giữa compiler và phần cứng mới ảnh hưởng lớn hơn nhiều

 
aer0700 2026-01-16

Trung bình thì tôi không rõ ngôn ngữ nào là nhanh nhất, nhưng có vẻ độ phân tán của C++ sẽ là lớn nhất.

 
jokerized 2026-01-16

Trong lĩnh vực hệ thống nhúng, người ta còn lập trình với cả việc tính đến kích thước cache line của phần cứng. Vấn đề có lẽ nằm ở chỗ lập trình viên có thể tối ưu hóa đến cực hạn trên ngôn ngữ được bao xa, cùng với hiệu năng của thư viện chuẩn và trình biên dịch. Dù sao thì cả hai đều hỗ trợ mức thấp, nên khác biệt về một chút overhead có lẽ cũng chỉ ở mức không đáng kể. Vì vậy đây có vẻ không phải là một cuộc tranh luận quá có ý nghĩa.. Nếu cần tối ưu hóa đến mức cực hạn thì cuối cùng vẫn phải có sự can thiệp của con người. Vì trình biên dịch không hoàn hảo như ta nghĩ.

 
iolothebard 2026-01-15

Tôi nghĩ Rust sẽ trở thành lựa chọn thay thế cho C++ hơn là cho C. C gần như là ngôn ngữ duy nhất (có lẽ cũng là cuối cùng) mà người ta có thể đoán được trình biên dịch sẽ tạo ra mã như thế nào…

 
galadbran 2026-01-16

Có phải bạn cố ý làm vậy đúng không, hừ hừ.

 
winmain 2026-01-15

Điều đó phụ thuộc vào năng lực của trình biên dịch.

Nếu lắp ráp cùng một đoạn mã thì sẽ ra ngay thôi.