การอพิจารณาเรื่อง resizable structs ใน Zig เมื่อเร็วๆ นี้ได้จุดประกายการถกเถียงอย่างเข้มข้นในชุมชนเกี่ยวกับการตัดสินใจออกแบบพื้นฐานของภาษา โดยเฉพาะอย่างยิ่งเรื่อง stack allocation และ Variable Length Arrays (VLAs) สิ่งที่เริ่มต้นเป็นบทความทางเทคนิคที่เสนอโครงสร้างข้อมูลใหม่ได้พัฒนาไปสู่การสนทนาในวงกว้างเกี่ยวกับกลยุทธ์ async I/O ที่กำลังจะมาของ Zig และผลกระทบต่อนักพัฒนา
ข้อจำกัดของ Async I/O ที่เปลี่ยนแปลงทุกอย่าง
ความขัดแย้งมีจุดศูนย์กลางอยู่ที่การตัดสินใจของ Zig ในการยกเว้น VLAs ออกจากข้อกำหนดของภาษา Andy Kelley ผู้สร้าง Zig เปิดเผยว่าข้อจำกัดนี้มีความสำคัญต่อการใช้งาน async I/O ที่กำลังจะมาของภาษา คอมไพเลอร์จำเป็นต้องคำนวณการใช้งาน stack สูงสุดสำหรับการเรียกใช้ฟังก์ชัน ซึ่งจะเป็นไปไม่ได้หากมีการจัดสรร stack ที่ทราบขนาดในขณะรันไทม์ การตัดสินใจออกแบบนี้มีผลกระทบในวงกว้างที่ขยายไปเกินกว่าการจัดการหน่วยความจำแบบง่ายๆ
กลยุทธ์ async I/O ยังส่งผลต่อการทำงานของ recursion ใน Zig ด้วย เนื่องจากโค้ดทั้งหมดอยู่ในหน่วยคอมไพล์เดียว คอมไพเลอร์สามารถวิเคราะห์กราฟการเรียกใช้ฟังก์ชันทั้งหมดได้ เมื่อพบรอบ (recursion) จะเกิดข้อผิดพลาด นักพัฒนาต้องใช้ builtin ของภาษาเพื่อเรียกใช้ฟังก์ชันด้วย stack ที่แตกต่างกัน ซึ่งโดยทั่วไปจะได้มาจากการจัดสรร heap
หมายเหตุ: VLAs (Variable Length Arrays) คืออาร์เรย์ที่มีขนาดกำหนดในขณะรันไทม์แทนที่จะเป็นเวลาคอมไพล์
ข้อจำกัดการจัดสรร Stack ของ Zig :
- ไม่มี Variable Length Arrays (VLAs) ในข้อกำหนดของภาษา
- คอมไพเลอร์ต้องคำนวณขีดจำกัดบนของการใช้งาน stack สำหรับ async I/O
- การเรียกซ้ำ (Recursion) ทำให้เกิดข้อผิดพลาดในการคอมไพล์ในกราฟการเรียกใช้ฟังก์ชัน
- นักพัฒนาต้องใช้ builtin ของภาษาสำหรับฟังก์ชันแบบเรียกซ้ำที่มี stack แยกต่างหาก
- โค้ดทั้งหมดอยู่ในหน่วยคอมไพเลชันเดียวเพื่อการวิเคราะห์ที่สมบูรณ์
ชุมชนต่อต้านการแลกเปลี่ยนประสิทธิภาพ
นักพัฒนาจำนวนมากตั้งคำถามว่าประโยชน์ของ async I/O นั้นคุ้มค่ากับต้นทุนด้านประสิทธิภาพหรือไม่ ผู้วิพากษ์วิจารณ์โต้แย้งว่าการจัดสรรสำหรับสถานการณ์เลวร้ายที่สุดเสมอจะเป็นการเสียหน่วยความจำและส่งผลเสียต่อประสิทธิภาพของแคช พวกเขาเสนอทางเลือกอื่นเช่นการจัดสรรที่มีขอบเขตในเวลาคอมไพล์ที่สามารถให้ locality ของหน่วยความจำที่ดีกว่าในขณะที่ยังคงความสามารถของคอมไพเลอร์ในการคำนวณขอบเขตของ stack
การถกเถียงได้เผยให้เห็นความตึงเครียดพื้นฐานระหว่างความปลอดภัยและประสิทธิภาพ สมาชิกชุมชนบางคนรู้สึกว่าแนวทางของ Zig เสียสละความยืดหยุ่นมากเกินไปเพื่อประโยชน์เชิงทฤษฎีที่นักพัฒนาหลายคนอาจไม่เคยใช้ ขณะที่คนอื่นๆ ปกป้องการตัดสินใจนี้ว่าจำเป็นสำหรับการสร้างภาษาที่คาดเดาได้และปลอดภัยมากขึ้น
ข้อกังวลของชุมชน:
- ผลกระทบต่อประสิทธิภาพจากการจัดสรรหน่วยความจำในกรณีเลวร้ายที่สุด
- การลดลงของ memory locality ส่งผลกระทบต่อประสิทธิภาพของ cache
- ความสามารถในการทำงานร่วมกันกับไลบรารี C และ function pointer ที่จำกัด
- ความท้าทายสำหรับการคอมไพล์แบบกระจายและแบบเพิ่มเติม
- การสูญเสียการควบคุมระดับต่ำเมื่อเปรียบเทียบกับภาษาระบบอื่นๆ
แนวทางทางเลือกและวิธีแก้ไขชั่วคราว
แม้จะมีข้อจำกัด นักพัฒนาได้หาทางแก้ไขที่สร้างสรรค์ ชุมชนได้สำรวจการใช้ opaque types และการจัดการหน่วยความจำด้วยตนเองเพื่อให้ได้ฟังก์ชันการทำงานที่คล้ายคลึงกัน บางคนแนะนำให้ใช้ stack-allocated buffers เป็น backing stores ทำให้นักพัฒนาสามารถจัดการกับความล้มเหลวอย่างสง่างามแทนที่จะเสี่ยงต่อการ crash จาก stack overflow
การอพิจารณายังเน้นให้เห็นว่าข้อจำกัดเหล่านี้ส่งผลต่อการทำงานร่วมกับไลบรารี C และ function pointers อย่างไร ข้อกำหนดของหน่วยคอมไพล์เดียวสร้างความท้าทายสำหรับการคอมไพล์แบบกระจายและการ build แบบเพิ่มทีละส่วน แม้ว่านักพัฒนาจะสังเกตว่าการแคชและการทำงานแบบขนานสามารถลดปัญหาเหล่านี้ได้บ้าง
วิธีการแก้ไขปัญหาและทางเลือกที่เสนอ:
- ใช้ opaque types พร้อมการจัดการหน่วยความจำแบบแมนนวล
- บัฟเฟอร์ที่จัดสรรบน stack เป็นที่เก็บข้อมูลสำรองพร้อมการจัดการข้อผิดพลาด
- การจัดสรรแบบมีขอบเขตในเวลาคอมไพล์พร้อมพารามิเตอร์ขีดจำกัดบน
- การใช้งาน recursion แบบแมนนวลในฟังก์ชันเดียว
- การจัดสรรบน heap เพื่อทำลายวงจร recursion
มองไปข้างหน้า
การถกเถียงสะท้อนคำถามในวงกว้างเกี่ยวกับปรัชญาการออกแบบภาษา ในขณะที่นักพัฒนาบางคนชื่นชมแนวทางที่มีความเห็นชัดเจนของ Zig ต่อความปลอดภัยและการคาดเดาได้ คนอื่นๆ กังวลเรื่องการสูญเสียการควบคุมระดับต่ำที่ดึงดูดพวกเขาไปสู่ภาษาโปรแกรมระบบ ชุมชนยังคงสำรวจวิธีการทำงานภายในข้อจำกัดเหล่านี้ในขณะที่รักษาลักษณะประสิทธิภาพที่ทำให้ Zig น่าสนใจ
เมื่อกลยุทธ์ async I/O ของ Zig พัฒนาขึ้น ชุมชนจะยังคงปรับปรุงแนวทางเหล่านี้และหาวิธีใหม่ๆ ในการสร้างสมดุลระหว่างความปลอดภัย ประสิทธิภาพ และการใช้งานของนักพัฒนา การอพิจารณาแสดงให้เห็นทั้งความหลงใหลของชุมชน Zig และการแลกเปลี่ยนที่ซับซ้อนที่เกี่ยวข้องในการออกแบบภาษาสมัยใหม่
อ้างอิง: Resizable structs in Zig