13 คะแนน โดย GN⁺ 2026-01-15 | 9 ความคิดเห็น | แชร์ทาง WhatsApp
  • การเปรียบเทียบประสิทธิภาพของ Rust และ C เป็นประเด็นที่ซับซ้อน ซึ่งขึ้นอยู่กับนิยามของสมมติฐานว่า “ทุกเงื่อนไขเหมือนกัน”
  • ในกรณีของ inline assembly ทั้งสองภาษาสามารถสร้างโค้ดแอสเซมบลีแบบเดียวกันได้ จึงไม่มีความต่างด้านความเร็วจากตัวภาษาเอง
  • ในเรื่อง การจัดวางหน่วยความจำของ struct Rust อาจมีขนาดเล็กกว่าได้จากการจัดเรียงฟิลด์ใหม่ แต่ก็สามารถใช้แอตทริบิวต์ #[repr(C)] เพื่อให้มี layout แบบเดียวกับ C ได้
  • เนื่องจากความต่างของ การตรวจสอบขณะรันไทม์และพฤติกรรมของนักพัฒนา โครงสร้างโค้ดและประสิทธิภาพในโปรเจกต์จริงจึงอาจแตกต่างกัน
  • สรุปคือ ไม่มีความต่างด้านประสิทธิภาพที่เกิดจากข้อจำกัดของภาษาเอง และผลลัพธ์จะต่างกันตามปัจจัยของโปรเจกต์และนักพัฒนา

การตั้งคำถามและความกำกวมของสมมติฐาน

  • จุดเริ่มต้นมาจากคำถามบน Reddit ว่า “ถ้าเงื่อนไขเหมือนกัน Rust จะเร็วกว่า C ได้หรือไม่”
  • คำว่า “ทุกเงื่อนไขเหมือนกัน” เองเป็นแนวคิดที่นิยามได้ยากมากในการเปรียบเทียบภาษา
  • การเปรียบเทียบประสิทธิภาพไม่ได้ขึ้นอยู่แค่ความต่างของภาษา แต่ยังขึ้นกับรูปแบบโค้ด การตัดสินใจของผู้พัฒนา และการเพิ่มประสิทธิภาพของคอมไพเลอร์

การเปรียบเทียบ inline assembly

  • Rust รองรับ inline assembly ในระดับภาษา ขณะที่ C ทำสิ่งนี้ผ่าน ความสามารถส่วนขยายของคอมไพเลอร์
    • ทั้งสองภาษาสามารถเขียนตัวอย่างเดียวกันที่ใช้คำสั่ง rdtsc ได้
    • แอสเซมบลีที่สร้างจาก rustc 1.87.0 และ clang 20.1.0 ออกมาเหมือนกันทุกประการ
  • กรณีนี้ไม่ได้แสดงให้เห็นความต่างด้านประสิทธิภาพของภาษา แต่พิสูจน์ว่า Rust สามารถควบคุมระดับล่างได้ในระดับเดียวกับ C

ความต่างของ layout ของ struct

  • struct ของ Rust สามารถ เพิ่มประสิทธิภาพการใช้หน่วยความจำด้วยการจัดเรียงฟิลด์ใหม่ ได้
    • ในตัวอย่าง struct ของ Rust มีขนาด 16 ไบต์ ส่วน struct เดียวกันใน C มีขนาด 24 ไบต์
  • ใน C ต้องเปลี่ยนลำดับฟิลด์ด้วยตนเองจึงจะได้ขนาดเท่ากัน
  • หากใช้แอตทริบิวต์ #[repr(C)] ใน Rust ก็สามารถบังคับให้มี layout หน่วยความจำแบบเดียวกับ C ได้

ปัจจัยทางสังคมและปัจจัยของนักพัฒนา

  • ด้วย การตรวจสอบความปลอดภัยของ Rust จึงมีกรณีที่นักพัฒนากล้าลองเพิ่มประสิทธิภาพเชิงรุกมากขึ้น
    • ในโปรเจกต์ Stylo ของ Mozilla ความพยายามทำ parallelization สองครั้งด้วย C++ ล้มเหลว แต่ทำสำเร็จเมื่อใช้ Rust
  • แม้จะเป็นโปรเจกต์เดียวกัน แต่ ประสิทธิภาพและความเสถียรของโค้ดที่ได้ ก็อาจต่างกันตามภาษาและความชำนาญของนักพัฒนา
  • ผลลัพธ์ของ “งานเดียวกัน” ย่อมต่างกันได้ตามระดับผู้เริ่มต้นหรือผู้เชี่ยวชาญ รวมถึงความคุ้นเคยกับภาษา จึงเทียบกันแบบตรงไปตรงมาได้ยาก

การตรวจสอบตอนคอมไพล์และตอนรันไทม์

  • การตรวจสอบด้านความปลอดภัยของ Rust จำนวนมากเกิดขึ้น ตอนคอมไพล์ แต่บางส่วนยังคงเป็นการตรวจสอบตอนรันไทม์
    • ตัวอย่างเช่น เมื่อเข้าถึง array[0] Rust จะทำ bounds check แต่ C จะไม่ทำ
    • หากใช้ get_unchecked() ใน Rust ก็จะได้พฤติกรรมแบบเดียวกับ C
  • หากคอมไพเลอร์พิสูจน์ความปลอดภัยได้ ทั้งสองภาษาก็สามารถ ตัดการตรวจสอบออกผ่านการ optimize ได้
  • ความต่างเหล่านี้ส่งผลต่อวิธีเขียนโค้ด และ ท้ายที่สุดอาจทำให้เกิดความต่างด้านประสิทธิภาพได้

บทสรุป

  • ต่อให้สมมติว่า C เป็น “ภาษาที่เร็วที่สุด” ก็ ไม่มีเหตุผลว่าทำไม Rust จะให้ประสิทธิภาพในระดับเดียวกันไม่ได้
  • มากกว่าข้อจำกัดของตัวภาษาเอง ปัจจัยที่ตัดสินความต่างด้านประสิทธิภาพคือ ลักษณะของโปรเจกต์ ความสามารถของนักพัฒนา ข้อจำกัดด้านเวลา และตัวแปรภายนอกอื่น ๆ
  • ดังนั้นคำถามว่า “Rust เร็วกว่า C หรือไม่?” ควรถูกมองว่าเป็น ประเด็นด้านบริบททางวิศวกรรมมากกว่าการเปรียบเทียบตัวภาษา

9 ความคิดเห็น

 
GN⁺ 2026-01-15
ความเห็นจาก Hacker News
  • สรุปคือ ความเร็วสูงสุด แทบไม่ต่างกัน แต่ในโค้ดจริงความต่างค่อนข้างชัด
    โดยเฉพาะ มัลติเธรดดิ้ง เป็นตัวแปรสำคัญ Rust บังคับให้ตัวแปร global ทั้งหมดต้อง thread-safe ไม่ว่าจะใช้เธรดหรือไม่ก็ตาม และ borrow checker ก็จำกัดการเข้าถึงหน่วยความจำให้เป็นได้แค่แบบแชร์หรือแบบแก้ไขอย่างใดอย่างหนึ่ง
    เพราะงั้นใน Rust การเขียนโค้ดหลายเธรดจึงแทบจะเป็นค่าเริ่มต้นไปแล้ว ในทางกลับกัน C เองแม้แต่การสร้างเธรดยังเป็นภาระเพราะปัญหาความเข้ากันได้ของแพลตฟอร์มและความเสี่ยงในการดีบัก

    • พูดตรง ๆ ผมคิดว่าความต่างพวกนี้ส่วนใหญ่เกิดจาก ความสะดวกของ standard library มากกว่า
      ใน C การสร้างเธรดไม่ถึงกับยาก แต่ก็ยุ่งยากกว่า Rust แบบ std::thread::spawn(move || { ... });
      มากกว่าความปลอดภัยของหน่วยความจำ สิ่งที่มีผลมากกว่าคือ โมเดล concurrency ของภาษา Go ก็ทำงานขนานได้ง่ายด้วย go f() แม้จะไม่ memory-safe
      ส่วนตัวผมกลับเจอ heisenbug ใน Go บ่อยกว่า
    • นอกจากมัลติเธรดดิ้งแล้ว ก็สงสัยว่าระบบ type system ของ Rust ที่ให้ข้อมูลมากกว่าน่าจะเปิดช่องให้ optimize ได้มากขึ้นหรือเปล่า
    • จริง ๆ แล้วแค่ #pragma omp for บรรทัดเดียวก็ทำ parallelize ใน C ได้ง่ายเหมือนกัน
    • ยังงงอยู่เลยว่าทำไมการทำมัลติเธรดบน Linux ถึงต้อง ลิงก์ TBB ด้วย คิดว่าน่าจะมีมาให้เป็นค่าเริ่มต้น
    • ถ้าเพิ่มเธรดแบบไม่ยั้ง ก็ต้องคิดด้วยว่า การใช้พลังงาน กับ race condition จะเป็นยังไง
  • ด้วย traits ของ Rust จึงสร้าง abstraction ที่ทั้งเร็วและยืดหยุ่นกว่าได้
    ใน C พอเลียนแบบได้ด้วยแมโครหรือฟังก์ชันพอยน์เตอร์ แต่ใน Rust ผู้เรียกสามารถเลือกได้ว่าจะใช้ dynamic dispatch หรือ static dispatch
    ในสภาพแวดล้อม embedded ฟังก์ชันพอยน์เตอร์ทำให้ cache เสียและลดประสิทธิภาพ แต่ Rust traits เปิดทางให้ inline optimization ได้ จึงมีประสิทธิภาพกว่ามาก

    • ผมก็ชอบการ hack ELF เหมือนกัน แต่ถ้าจะเอาประสิทธิภาพก็ต้องรู้เรื่อง linker, ABI และ binary format ให้ดี
      จะ Rust หรือ C สุดท้ายก็ต้องจัดการกันในระดับไบต์อยู่ดี และทุกวันนี้เครื่องมือ binary patching ก็พัฒนาดีขึ้นจนใช้งานง่าย
    • แน่นอนว่าใน Rust เอง ถ้าใส่ Box<dyn Trait> ใน function signature ก็เท่ากับบังคับให้ผู้เรียกใช้ dynamic dispatch
      แต่ถ้าใช้ impl Trait ผู้เรียกก็ยังมีสิทธิ์เลือกได้
    • แต่ถ้าใช้ traits เยอะมาก เวลา build ที่เพิ่มขึ้น จะเห็นได้ชัด ยิ่ง trait ซับซ้อนเท่าไร คอมไพล์ก็ยิ่งช้า
    • แนวทางแบบ C คือ หลีกเลี่ยง abstraction ไปเลย
  • ส่วนตัวผมมองว่า Rust, C และ C++ เป็น ตระกูลภาษา low-level ที่ใกล้กันมากอยู่แล้ว ดังนั้นความต่างด้านประสิทธิภาพจึงน้อยมาก
    กฎ aliasing ที่เข้มงวด ของ Rust เอื้อต่อการ optimize ขณะที่ UB (undefined behavior) ของ C/C++ ก็มีอยู่เพื่อแลกกับประสิทธิภาพ
    และ generics ของ Rust กับ C++ ก็ทรงพลังกว่า C มาก เช่น ถ้าเทียบการ sort ด้วยเทมเพลตกับ qsort() แบบเดิม การทำ inline optimization ก็ง่ายกว่าเยอะ

    • เทมเพลตของ C++ ยังมี พลังในการแสดงออก สูงกว่า Rust อยู่ แต่ช่องว่างก็ค่อย ๆ แคบลง
    • จริง ๆ แล้วนี่เป็นปัญหาเรื่อง การออกแบบ standard library มากกว่าตัวภาษา ใน C เองก็เขียนฟังก์ชัน sort ที่ inline ได้ด้วยตัวเอง
    • การจัดการ integer overflow ของ Rust อิงตามพฤติกรรมปกติของแพลตฟอร์ม จึงอาจให้ผลต่างกันตามการ optimize
    • ภาษาเป็นแค่ เครื่องมือสำหรับอธิบายพฤติกรรม เท่านั้น ความเร็วจริงขึ้นกับคอมไพเลอร์และสภาพแวดล้อมรันไทม์
    • สุดท้ายความต่างด้านประสิทธิภาพของทั้งสามภาษาก็เป็นเรื่องของ ความคุ้มค่าต่อแรงที่ลงไป C เร็ว แต่ต้นทุนการพัฒนาสูง ส่วน Rust อยู่ตรงกลาง
  • ผมคิดว่าการถกเถียงเรื่อง ความเร็วของภาษา แบบนี้ส่วนใหญ่ไม่มีความหมายเท่าไร
    สิ่งที่กำหนดประสิทธิภาพจริง ๆ คือ การ implement ของคอมไพเลอร์ มากกว่าตัวภาษา

    • ถึงอย่างนั้น การออกแบบภาษาก็มีผลมากต่อ ความเป็นไปได้ในการ optimize คอมไพเลอร์ที่ ‘ฉลาดพอ’ ยังเป็นแค่ เรื่องเล่าในอุดมคติ เท่านั้น
  • Rust, C และ C++ ต่างก็เป็น ภาษา low-level แต่คำว่า “เร็ว” ต้องนิยามให้ชัด
    กำลังพูดถึงความเร็วสูงสุดของโค้ดที่ผู้เชี่ยวชาญ optimize แล้ว หรือกำลังพูดถึง โอกาสที่นักพัฒนาทั่วไปจะเขียนโค้ดเร็วได้ภายในงบประมาณที่มี กันแน่

    • ในทางปฏิบัติ ความสามารถในการ optimize ของคอมไพเลอร์ คือหัวใจสำคัญ semantics ด้านหน่วยความจำของ Rust มีรายละเอียดมากกว่า จึงให้ข้อมูลกับคอมไพเลอร์เพื่อ optimize ได้มากขึ้น
      แต่ถ้าปรับแต่งด้วยมือเต็มที่ ความต่างระหว่างภาษาก็แทบหายไป
      อย่างไรก็ตาม Rust ยังพอได้เปรียบเล็กน้อยตรงที่เป็น ภาษาที่เขียนโค้ดเร็วให้เร็วได้ง่ายกว่า
    • คนส่วนใหญ่มักใช้คำนิยามแบบ “ภาษาไหนที่นักพัฒนาทั่วไปเขียนโค้ดเร็วได้ง่ายกว่า”
    • ผู้ออกแบบภาษามักคิดถึงคำถามว่า ‘โค้ดแบบฉบับของภาษานี้จะเร็วได้แค่ไหน’ ดังนั้นผมว่าคำถามนี้ยังมีความหมาย
  • เดิมทีผมคิดว่าจุดเด่นของ Rust คือ มัลติเธรดดิ้ง กับ การจัดสรรบนสแต็ก
    ด้วยโมเดล ownership มันจึงเอาของไปวางบนสแต็กได้มากกว่า C/C++ และช่วยลด โอเวอร์เฮดของ malloc/free

    • ใช่ แต่การคุยครั้งนี้โฟกัสที่ การเปรียบเทียบเชิงแนวคิดในมุมการออกแบบภาษา มากกว่าความต่างเชิงรายละเอียดแบบนั้น
      ประเด็นแนวนี้มักเถียงกันด้วยอารมณ์เยอะ เลยอยากพูดถึง ความต่างของกรอบความคิด มากกว่าตัวเลขเฉพาะเจาะจง
  • เวลาพูดถึง “ความเร็ว” ของภาษา ต้องดูอยู่สองอย่าง

    1. ภาษานั้น เพิ่มต้นทุนอะไรเข้าไปในโปรแกรม บ้าง
    2. ภาษานั้น เปิดทางให้ optimize อะไรได้บ้าง
      Rust กับ C แทบไม่มี runtime check จึงเร็วกว่าพวก Python หรือ JS
      แต่ Rust ส่งข้อมูลเรื่อง aliasing ให้คอมไพเลอร์ได้ดีกว่า จึงมีพื้นที่ให้ optimize มากกว่า
      ในโหมด debug มันช้าได้พอ ๆ กับ Ruby แต่ในโหมด release ก็ทำความเร็วได้ระดับ C
    • ผมชอบมุมมองนี้ มันเชื่อมกับแนวคิด zero-cost abstraction ของ C++ ด้วย
    • JS เองก็ถูก optimize มามาก แต่ก็ยังช้ากว่า Rust/C อยู่นิดหน่อย
    • อีกคำถามหนึ่งคือ “ถ้านักพัฒนาทั่วไปเอาไปใช้ มันจะเร็วแค่ไหน” ภาษาที่ชี้นำให้เขียนโค้ดเร็วเป็นค่าปกติย่อมสำคัญ
  • เมื่อเทียบกับ C แล้ว C++ หรือ Rust มี ความสามารถฝั่ง compile time ที่มากกว่า จึงเขียนโค้ดเร็วได้ง่ายกว่า
    ตัวอย่างเช่น โค้ดนี้ แทบเป็นไปไม่ได้เลยใน C

    • อีกตัวอย่างก็มี CTRE หรือ compile API ของ fmt
      ถ้าเป็น C จะต้องพึ่ง เครื่องมือภายนอก อย่าง re2c
  • เนื่องจากแอสเซมบลีไม่ได้เป็นส่วนหนึ่งของมาตรฐาน C จึงเทียบกับ Rust โดยตรงได้ยาก และ Rust เองก็มีลักษณะใกล้กับ โปรเจกต์ GCC มากกว่า

  • สุดท้ายแล้วภาษาไหนจะ “เร็ว” ก็ขึ้นอยู่กับ implementation และบริบท
    มากกว่าความเร็วของตัวภาษาเอง สิ่งที่มีผลมากกว่าคือ การจับคู่กันของคอมไพเลอร์กับฮาร์ดแวร์

 
aer0700 2026-01-16

โดยเฉลี่ยแล้วผมไม่แน่ใจว่าภาษาไหนเร็วที่สุด แต่คิดว่าความกระจายของผลลัพธ์น่าจะมากที่สุดสำหรับ C++

 
jokerized 2026-01-16

ในงาน embedded เราเขียนโค้ดโดยคำนึงถึงขนาด cache line ของฮาร์ดแวร์ด้วยอยู่แล้ว ประเด็นคงอยู่ที่ว่านักพัฒนาจะทำ optimization ขั้นสุดบนระดับภาษาได้ไกลแค่ไหน รวมถึงเรื่องประสิทธิภาพของ standard library และ compiler แต่ยังไงทั้งคู่ก็รองรับงาน low-level เหมือนกัน ดังนั้นความต่างของ overhead เล็กน้อยก็น่าจะอยู่ในระดับที่แทบไม่มีนัยสำคัญ เพราะงั้นเลยดูไม่ใช่ประเด็นถกเถียงที่มีความหมายเท่าไรนัก.. ถ้าต้องการ optimization แบบสุดทาง สุดท้ายก็ต้องอาศัยการแทรกแซงของมนุษย์อยู่ดี เพราะ compiler ไม่ได้สมบูรณ์แบบอย่างที่คิด

 
iolothebard 2026-01-15

ผมคิดว่า Rust น่าจะเป็นตัวแทนของ C++ มากกว่า C สำหรับ C แล้ว มันแทบจะเป็นภาษาเดียว (หรืออาจเป็นภาษาสุดท้าย) ที่เราพอจะคาดเดาโค้ดที่คอมไพเลอร์สร้างออกมาได้…

 
secret3056 2026-01-16

zig ก็ไม่เลวนะ... ฮือ

 
iolothebard 2026-01-15

พอเขียนไปเขียนมา มันกลายเป็นสไตล์สรุปโดย AI ซะงั้น ฮือๆ

 
galadbran 2026-01-16

ไม่ได้ตั้งใจแกล้งกันใช่ไหมครับ ฮุฮุ

 
winmain 2026-01-15

ขึ้นอยู่กับความสามารถของคอมไพเลอร์

ถ้าลองแอสเซมเบิลโค้ดเดียวกันดูก็น่าจะรู้ครับ

 
jjw9512151 2026-01-15

ดูเหมือนว่าฝั่งพี่ ๆ ffmpeg จะคิดว่า rust ไม่ได้เร็วกว่า c นะ 555 https://www.memorysafety.org/blog/rav1d-perf-bounty/