การนำเสนอล่าสุดเกี่ยวกับเทคนิคการเพิ่มประสิทธิภาพขั้นสูงของ Rust ได้จุดประกายการถกเถียงอย่างเข้มข้นในชุมชนนักพัฒนาโปรแกรมเกี่ยวกับความสมดุลระหว่างความปลอดภัยและประสิทธิภาพ เทคนิคเหล่านี้ซึ่งได้รับการสาธิตในโปรเจค Wild linker แสดงให้เห็นวิธีการที่ชาญฉลาดในการหลีกเลี่ยงกฎความปลอดภัยหน่วยความจำที่เข้มงวดของ Rust ขณะที่ยังคงรักษาการเพิ่มประสิทธิภาพไว้
ประเด็นหลักของการถกเถียง: การแลกเปลี่ยนระหว่างความปลอดภัยและประสิทธิภาพ
จุดแย้งหลักมุ่งเน้นไปที่ว่าเทคนิคการเพิ่มประสิทธิภาพเหล่านี้บ่อนทำลายข้อเสนอคุณค่าหลักของ Rust หรือไม่ นักวิจารณ์โต้แย้งว่าวิธีการเหล่านี้เป็นเพียงการหลีกเลี่ยงที่ซับซ้อนสำหรับ borrow checker ของ Rust โดยนักพัฒนาคนหนึ่งสังเกตว่าแนวทางเหล่านี้พึ่พาการเพิ่มประสิทธิภาพของคอมไพเลอร์อย่างมากซึ่งอาจเสียหายระหว่างการปล่อยเวอร์ชันใหม่ ข้อกังวลคือ debug builds ยังคงช้ากว่า release builds อย่างมีนัยสำคัญ และการเพิ่มประสิทธิภาพยากต่อการตรวจสอบเมื่อเปรียบเทียบกับบล็อกโค้ด unsafe ที่ตรงไปตรงมา
อย่างไรก็ตาม ผู้สนับสนุนโต้แย้งว่าเทคนิคเหล่านี้ช่วยให้เกิดการประมวลผลแบบขนานที่ปลอดภัยขณะที่รักษาการรับประกันความปลอดภัยของเธรดของ Rust พวกเขาชี้ให้เห็นว่าการแสดงอัลกอริทึมในรูปแบบที่ borrow checker ยอมรับทำให้การดำเนินการแบบขนานเป็นไปได้โดยใช้เครื่องมืออย่าง Rayon ซึ่งเป็นสิ่งที่จะท้าทายและเสี่ยงต่อข้อผิดพลาดมากกว่าในภาษาอย่าง C หรือ C++
ข้อกังวลของชุมชนเทียบกับผลประโยชน์
ข้อกังวล:
- การพึ่งพาการปรับแต่งของ compiler ที่อาจเสียหายระหว่างการอัปเดตเวอร์ชัน
- Debug builds ยังคงช้ากว่า release builds อย่างมีนัยสำคัญ
- เทคนิคต่างๆ ยากต่อการตรวจสอบเมื่อเปรียบเทียบกับโค้ด unsafe ที่ชัดเจน
- วิธีแก้ไขปัญหาที่ซับซ้อนอาจบ่งชี้ถึงข้อจำกัดของภาษา
ผลประโยชน์:
- รักษาการรับประกันความปลอดภัยของเธรดใน Rust
- เปิดใช้งานการประมวลผลแบบขนานที่ปลอดภัยด้วยเครื่องมืออย่าง Rayon
- บรรลุการแยกส่วนที่ไม่มีต้นทุนโดยไม่ต้องใช้บล็อก unsafe
- ให้การตรวจสอบความปลอดภัยในเวลาคอมไพล์
ความท้าทายในการใช้งานทางเทคนิค
เทคนิคการเพิ่มประสิทธิภาพเกี่ยวข้องกับการแปลงระหว่างประเภท atomic และ non-atomic การใช้การจัดสรรหน่วยความจำซ้ำในประเภทข้อมูลที่แตกต่างกัน และการเริ่มต้นแบบขนานของโครงสร้างข้อมูลขนาดใหญ่ แม้ว่าวิธีการเหล่านี้จะหลีกเลี่ยงบล็อกโค้ด unsafe แต่ก็ขึ้นอยู่กับการเพิ่มประสิทธิภาพของคอมไพเลอร์เฉพาะเพื่อให้บรรลุ zero-cost abstractions ชุมชนแบ่งออกเป็นสองฝ่ายว่าแนวทางนี้เชื่อถือได้มากกว่าการใช้โค้ด unsafe อย่างชัดเจนกับการดำเนินการ transmute หรือไม่
นักพัฒนาบางคนโต้แย้งว่าการพึ่พาการเพิ่มประสิทธิภาพการใช้ heap allocation ซ้ำของไลบรารีมาตรฐาน Rust สร้างโค้ดที่เปราะบางซึ่งอาจเสียหายเมื่อมีการอัปเดตคอมไพเลอร์ คนอื่นๆ ชื่นชมการตรวจสอบความปลอดภัยในเวลาคอมไพล์และความสามารถในการทำงานกับ abstractions ระดับสูงขณะที่ยังคงบรรลุประสิทธิภาพระดับ C
เทคนิคประสิทธิภาพหลักที่กล่าวถึง
- Mutable Slicing สำหรับ Threading: การใช้
split_at_mut
เพื่อสร้าง mutable slices ที่ไม่ทับซ้อนกันสำหรับการประมวลผลแบบขนาน - การเริ่มต้น Vec แบบขนาน: การใช้ uninitialised crate เพื่อหลีกเลี่ยงค่าใช้จ่ายเพิ่มเติมจากค่า placeholder
- การแปลงแบบ Atomic/Non-Atomic: การแปลงแบบไม่มีต้นทุนระหว่างประเภท
Symbol
และAtomicSymbol
- การใช้ Buffer ซ้ำ: การแปลงประเภท Vec เพื่อใช้การจัดสรร heap ซ้ำในช่วง lifetimes ที่แตกต่างกัน
- การยกเลิกการจัดสรรในพื้นหลัง: การย้ายการยกเลิกการจัดสรรหน่วยความจำขนาดใหญ่ไปยัง threads แยกต่างหากโดยใช้
rayon::spawn
ผลกระทบที่กว้างขึ้นสำหรับการเขียนโปรแกรมระบบ
การถกเถียงสะท้อนคำถามที่ใหญ่กว่าเกี่ยวกับตำแหน่งของ Rust ในการเขียนโปรแกรมระบบ แม้ว่าภาษานี้จะสัญญาทั้งความปลอดภัยและประสิทธิภาพ แต่การบรรลุประสิทธิภาพที่เหมาะสมที่สุดบางครั้งต้องการการทำงานที่ขัดกับรูปแบบธรรมชาติของภาษา สิ่งนี้ทำให้นักพัฒนาบางคนตั้งคำถามว่าความซับซ้อนของการหลีกเลี่ยงเหล่านี้สมเหตุสมผลที่จะใช้ Rust แทนภาษาการเขียนโปรแกรมระบบแบบดั้งเดิมหรือไม่
การถกเถียงยังเน้นย้ำถึงวิวัฒนาการที่กำลังดำเนินอยู่ของระบบนิเวศของ Rust ที่นักพัฒนากำลังค้นหาโซลูชันสร้างสรรค์เพื่อขยายขอบเขตของสิ่งที่เป็นไปได้ภายในข้อจำกัดความปลอดภัยของภาษา เมื่อภาษาเติบโตขึ้น เทคนิคเหล่านี้อาจมีอิทธิพลต่อคุณสมบัติภาษาในอนาคตหรือการปรับปรุงไลบรารีมาตรฐาน
การตอบสนองของชุมชนแสดงให้เห็นว่าแม้เทคนิคการเพิ่มประสิทธิภาพเหล่านี้จะน่าประทับใจจากมุมมองทางเทคนิค แต่ไม่มีฉันทามติว่าสิ่งเหล่านี้แสดงถึงแนวปracticeที่ดีที่สุดหรือความชั่วร้ายที่จำเป็นในการพัฒนา Rust ประสิทธิภาพสูง
อ้างอิง: Wild Performance Tricks