1 คะแนน โดย GN⁺ 2025-06-08 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • การเพิ่มประสิทธิภาพระดับล่าง สามารถทำได้อย่างสะดวกในภาษา Zig
  • แม้ว่าโดยมากแล้ว คอมไพเลอร์ จะทำการปรับแต่งประสิทธิภาพได้ดี แต่บางครั้งการสื่อเจตนาของโปรแกรมเมอร์ให้ชัดเจนก็ช่วยให้ได้ประสิทธิภาพที่ดีกว่า
  • Zig รองรับการสร้างโค้ดประสิทธิภาพสูงและเมตาโปรแกรมมิงที่ทรงพลังด้วยความสามารถ comptime (การทำงานขณะคอมไพล์)
  • เมื่อเทียบกับ Rust แล้ว Zig สามารถปรับแต่งได้ละเอียดกว่า ผ่าน annotation และโครงสร้างโค้ดที่เขียนอย่างชัดเจน
  • ในงานที่ต้องทำซ้ำอย่าง การเปรียบเทียบสตริง สามารถใช้ comptime เพื่อสร้างโค้ดแอสเซมบลีที่ดีกว่าฟังก์ชันทั่วไปได้

การเพิ่มประสิทธิภาพและ Zig

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

เราจะเชื่อใจคอมไพเลอร์ได้หรือไม่?

  • โดยทั่วไปมักมีคำแนะนำว่า “เชื่อใจคอมไพเลอร์” แต่ในความเป็นจริงก็มีกรณีที่ คอมไพเลอร์ทำงานต่างจากที่คาด หรือแม้กระทั่งละเมิดข้อกำหนดของภาษา
  • ภาษาระดับสูงมีข้อจำกัดด้านประสิทธิภาพ เพราะสื่อ เจตนา (intent) ได้ไม่ชัดเจน
  • ภาษาระดับล่างทำให้คอมไพเลอร์รู้ข้อมูลที่จำเป็นต่อการปรับแต่งได้จาก ความชัดเจนของโค้ด ตัวอย่างเช่นเมื่อเปรียบเทียบฟังก์ชัน maxArray ใน JavaScript กับ Zig นั้น Zig สามารถส่งข้อมูลเรื่องชนิดข้อมูล การจัดแนว และการมี alias หรือไม่ ให้ทราบตั้งแต่ตอนคอมไพล์แทนที่จะไปรู้ตอนรันไทม์
  • หากเขียนการทำงาน maxArray แบบเดียวกันด้วย Zig และ Rust ก็จะได้โค้ดแอสเซมบลีประสิทธิภาพสูงที่แทบเหมือนกัน แต่ ยิ่งแสดงเจตนาได้ดีเท่าไร ผลลัพธ์ของการปรับแต่งก็ยิ่งดีขึ้น
  • อย่างไรก็ตาม เราไม่อาจเชื่อมั่นในประสิทธิภาพของคอมไพเลอร์ได้เสมอไป ดังนั้นในจุดคอขวดจึงควร ตรวจดูทั้งโค้ดและผลลัพธ์จากการคอมไพล์ด้วยตนเอง แล้วหาวิธีปรับแต่งเพิ่มเติม

บทบาทของ Zig

  • Zig สามารถสร้าง โค้ดที่ผ่านการปรับแต่งอย่างดีโดยไม่ต้องพึ่งข้อมูลเชิงนามธรรม ได้ ด้วยคุณสมบัติอย่าง ความชัดเจนที่แม่นยำ ฟังก์ชัน built-in ที่หลากหลาย pointer และ annotation, comptime และ Illegal Behavior ที่นิยามไว้อย่างชัดเจน
  • Rust รับประกันโดยพื้นฐานจาก memory model ว่าอาร์กิวเมนต์จะไม่ alias กัน แต่ใน Zig ผู้พัฒนาต้อง ใส่ annotation อย่าง noalias ด้วยตนเอง
  • หากพิจารณาจาก LLVM IR เพียงอย่างเดียว ระดับการปรับแต่งของ Zig ก็ถือว่าสูง
  • ที่สำคัญที่สุดคือ comptime (การทำงานขณะคอมไพล์) ของ Zig เป็นเครื่องมือเพิ่มประสิทธิภาพที่ทรงพลังมาก

comptime คืออะไร?

  • comptime ของ Zig ถูกนำไปใช้ในการสร้างโค้ด การฝังค่า constant และการสร้าง generic struct ตามชนิดข้อมูล ซึ่งมีบทบาทสำคัญต่อการเพิ่มประสิทธิภาพขณะรันไทม์
  • สามารถใช้ comptime เพื่อทำ เมตาโปรแกรมมิง ได้
  • ต่างจาก macro ใน C/C++ หรือระบบ macro ของ Rust ตรงที่ comptime เป็น โค้ดปกติ ไม่ใช่ไวยากรณ์แยกต่างหาก
  • โค้ด comptime ไม่ได้แก้ไข AST โดยตรง แต่สามารถตรวจสอบ สะท้อนผล และสร้างสิ่งต่าง ๆ สำหรับทุกชนิดข้อมูลได้ในช่วงคอมไพล์
  • ความยืดหยุ่นของ comptime ยังส่งอิทธิพลต่อการพัฒนาของภาษาอื่นอย่าง Rust ด้วย และถูกผสานเข้ากับภาษา Zig อย่างเป็นธรรมชาติ

ข้อจำกัดของ comptime

  • ความสามารถของ macro บางอย่าง เช่น token-pasting ไม่สามารถแทนที่ด้วย comptime ของ Zig ได้
  • Zig ให้ความสำคัญกับ ความอ่านง่ายของโค้ด จึงไม่อนุญาตให้สร้างตัวแปรหรือกำหนด macro แบบออกนอกขอบเขต
  • แต่ในทางกลับกัน Zig comptime ก็มีตัวอย่างการใช้งานด้านเมตาโปรแกรมมิงอย่างกว้างขวาง เช่น type reflection, การสร้าง DSL และการปรับแต่งการ parse สตริงให้มีประสิทธิภาพ

การเพิ่มประสิทธิภาพการเปรียบเทียบสตริงด้วย comptime

  • ฟังก์ชันเปรียบเทียบสตริงแบบทั่วไปนั้นสามารถเขียนได้ในทุกภาษา แต่ใน Zig หากสตริงหนึ่งในสองตัวเป็น ค่าคงที่ที่รู้ตั้งแต่ตอน comptime ก็สามารถสร้างโค้ดแอสเซมบลีที่มีประสิทธิภาพกว่าได้
  • ตัวอย่างเช่น หากสตริงหนึ่งเป็น "Hello!\n" เสมอ ก็สามารถใช้การปรับแต่งแบบเปรียบเทียบเป็น บล็อกขนาดใหญ่กว่าในระดับไบต์ แทนการเทียบทีละไบต์
  • โดยใช้ comptime เราสามารถสร้างโค้ดประสิทธิภาพสูงตั้งแต่ตอนคอมไพล์ได้ ไม่ว่าจะเป็น เวกเตอร์ SIMD การประมวลผลแบบบล็อก หรือการปรับแต่งสำหรับไบต์ที่เหลือ
  • แนวทางนี้ไม่ได้ใช้ได้แค่กับการเปรียบเทียบสตริงซ้ำ ๆ เท่านั้น แต่ยังใช้สร้างโค้ดที่เน้นประสิทธิภาพสำหรับ แมปปิงจากข้อมูลคงที่ ตาราง perfect hash และตัวแยกวิเคราะห์ AST ได้อีกหลากหลาย

บทสรุป

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

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

 
GN⁺ 2025-06-08
ความคิดเห็นจาก Hacker News
  • สิ่งที่รู้สึกว่าน่าสนใจที่สุดใน zig คือความเรียบง่ายของ build system, cross compilation และการมุ่งไปที่ความเร็วในการทำซ้ำสูง ผมเป็นนักพัฒนาเกมจึงให้ความสำคัญกับประสิทธิภาพ แต่สำหรับความต้องการส่วนใหญ่แล้ว ภาษาส่วนใหญ่ก็ให้ประสิทธิภาพได้เพียงพออยู่แล้ว ดังนั้นมันจึงไม่ใช่เกณฑ์สำคัญที่สุดในการเลือกภาษา จะเขียนโค้ดที่ทรงพลังด้วยภาษาไหนก็ได้ แต่ผมตั้งเป้าไปที่เฟรมเวิร์กที่มองไกลในอนาคตและดูแลรักษาได้อีกหลายสิบปี C/C++ จึงเป็นตัวเลือกพื้นฐานเพราะได้รับการรองรับทุกที่ แต่ก็รู้สึกว่า zig อาจตามขึ้นมาได้ในระดับเดียวกัน
    • ผมลองเอา zig ไปรันบน Kindle รุ่นเก่ามากเครื่องหนึ่ง (Linux 4.1.15) เล่น ๆ แล้วประทับใจกับความสมบูรณ์ของ zig มาก หลายอย่างใช้ได้ทันที และยังสามารถดีบักบั๊กประหลาด ๆ ด้วย GDB เวอร์ชันเก่าได้ด้วย ผมเองก็หลงเสน่ห์ zig เหมือนกัน ดูประสบการณ์แบบละเอียดได้ที่นี่
    • ผมรู้สึกว่าสามารถเขียนโค้ดที่ทรงพลังได้ด้วยภาษาส่วนใหญ่ แต่ต้องการโค้ดแบบ modular ที่มองไปได้อีกหลายสิบปี ผมชอบ Zig แต่คิดว่ามันมีข้อเสียด้านการบำรุงรักษาระยะยาวและความเป็นโมดูลาร์ Zig เป็นภาษาที่ไม่เป็นมิตรกับ encapsulation ไม่สามารถทำสมาชิกของ struct ให้เป็น private ได้ คอมเมนต์ใน issue นี้ เป็นตัวอย่าง จุดยืนของ Zig คือไม่ควรมีสิ่งที่เรียกว่า internal representation แยกต่างหาก และผู้ใช้ทุกคนควรรู้รายละเอียดภายในผ่านการทำเอกสาร/เปิดเผย แต่ถ้าจะรักษา API contract ซึ่งเป็นแกนหลักของซอฟต์แวร์แบบ modular ก็จำเป็นต้องซ่อน implementation ภายในได้ และตอนนี้ทำไม่ได้ หวังว่าสักวัน Zig จะรองรับ private fields
    • ผมเคยลองใช้ Rust แบบผิวเผินแล้วชอบมัน แต่พอได้ยินคนพูดว่า "มันแย่" ก็หยุดไปพักหนึ่ง ตอนนี้กลับมาใช้อีกครั้งแล้วและก็ยังชอบอยู่ดี ไม่ค่อยเข้าใจว่าทำไมคนถึงเกลียดมันนัก syntax ของ generics ที่ดูไม่สวยนั้น C# กับ Typescript ก็เป็นเหมือนกัน ส่วน Borrow Checker ถ้ามีประสบการณ์กับภาษา low-level มาก็เข้าใจได้ไม่ยาก
    • Zig ให้ความรู้สึกเหมือน Rust ที่ง่ายกว่า และเหมือน Go ที่ดีกว่าอีกทางหนึ่ง ส่วนเครื่องมือที่สร้างบน zig นั้น ผมชอบ 'bun' มากถึงขั้นทึ่งจริง ๆ bun ทำให้ชีวิตสะดวกขึ้นมหาศาล ส่วน 'uv' ที่ทำด้วย Rust ก็ให้ประสบการณ์คล้ายกัน
    • เห็นด้วยที่ว่า C/C++ คือพื้นฐาน ความพยายามที่จะสร้างสิ่งที่ดีกว่า C ส่วนมากสุดท้ายก็มักจะกลายเป็น C++ ไปอยู่ดี ถึงอย่างนั้นก็ไม่ควรหยุดพยายาม Rust และ Zig เป็นหลักฐานว่ายังมีความหวังกับสิ่งที่ดีกว่า ตอนนี้ผมกะว่าจะไปเรียน C++ เพิ่มจากนี้
  • ต่อให้คอมไพเลอร์ล้ำสมัยบางครั้งจะละเมิดสเปกภาษา แต่สมมติฐานของ Clang ที่ว่าลูปไม่สิ้นสุดย่อมจบลงได้นั้น ถูกต้องตามมาตรฐานตั้งแต่ C11 เป็นต้นมา C11 ระบุไว้แบบนี้: "ลูปที่ control expression ไม่ใช่ constant expression และไม่มี I/O/volatile/sync/atomic operation คอมไพเลอร์สามารถสมมติได้ว่ามันจะสิ้นสุด"
    • ใน C++ (จนกว่าจะถึง C++26) กฎนี้ใช้กับทุกลูป แต่ตามที่คุณบอก สำหรับภาษา C จะใช้เฉพาะกับ "ลูปที่ control expression ไม่ใช่ constant expression" เท่านั้น กล่าวคือ ลูปอนันต์ที่ชัดเจนอย่าง for(;;); ต้องเป็นลูปไม่สิ้นสุดจริง ๆ และ loop {} ของ Rust ก็ควรเป็นแบบเดียวกัน แต่บางครั้งนักพัฒนา LLVM เหมือนจะเผลอคิดว่าตัวเองทำแต่คอมไพเลอร์ C++ พอ Rust บอกว่า "ขอลูปอนันต์นะ" LLVM ก็กลับใช้ตรรกะแบบ "ใน C++ ไม่มีทางเป็นแบบนั้น งั้น optimize เลย!" แล้วปัญหาก็เกิด เท่ากับเอา optimization ที่ผิดไปใช้กับภาษาที่ผิด
  • ถึงจะไม่มีความสามารถแบบ comptime ก็ยังสามารถ inline และ unroll การเปรียบเทียบสตริงใน C ได้สบาย ๆ ตัวอย่างที่เกี่ยวข้อง
    • ชี้ประเด็นได้ถูกต้อง! ตัวอย่างแรกง่ายเกินไปจริง ๆ ตัวอย่างที่ดีกว่าคือ คอมไพล์ไทม์ suffix automaton อีกอย่าง โค้ด godbolt ที่ลิงก์ไว้ข้างบนกลับแสดงหนึ่งในสองตัวอย่างของสิ่งที่ไม่ควรทำเสียด้วย
  • ผมคิดว่าส่วนที่บอกว่าโค้ด JavaScript ตัวอย่างสร้าง bytecode ที่ไม่มีประสิทธิภาพใน V8 นั้น ไม่ใช่ตัวอย่างเปรียบเทียบที่ดี คุณบอกให้ Zig กับ Rust คอมไพล์โดยระบุ environment ที่ใหม่มาก แต่กับ V8 กลับไม่ได้บังคับตัวเลือก optimization แบบเดียวกัน จริง ๆ แล้ว JIT สมัยใหม่ก็ vectorize ได้ถ้าสถานการณ์เอื้อ และภาษาสมัยใหม่ส่วนใหญ่ก็จัดการ optimization เกี่ยวกับสตริงคล้าย ๆ กัน อ้างอิง ตัวอย่างของ C++ ได้ด้วย
    • การเอา JS ไปเทียบกับ Zig แทบจะเหมือนเอาแอปเปิลไปเทียบกับฟรุตสลัด ตัวอย่าง Zig ใช้อาร์เรย์ที่ชนิดและขนาดตายตัว แต่ JS เป็นโค้ด 'generic' ที่มีชนิดข้อมูลหลายแบบเข้ามาได้ตอนรันไทม์ ด้วยเหตุนี้ใน JS ถ้าให้ข้อมูลชนิดได้ดี JIT ก็สร้างลูปที่เร็วขึ้นมากได้ (ถึงจะยังไม่ถึงขั้น vectorize ก็ตาม) ในทางปฏิบัติคนไม่ได้ใช้ TypedArray บ่อยนัก เพราะต้นทุนการ initialize สูง และคุ้มก็ต่อเมื่อเอากลับมาใช้ซ้ำบ่อย ๆ อีกอย่าง ในบทความบอกว่าโค้ด JS บวมเกินจริง แต่ส่วนใหญ่เป็นเพราะ JIT เชื่อการตรวจสอบความยาวอาร์เรย์ไม่ได้จึงต้องใส่ guard และในความเป็นจริงทุกคนก็เขียนลูปแบบ i < x.length กันอยู่แล้ว ทำให้ JIT optimize ได้ มุมนี้เลยอาจเป็นการจับผิดนิดหน่อย แม้จะเป็นความต่างเล็ก ๆ ก็ตาม
    • สามารถเปลี่ยน target ของตัวอย่าง godbolt ฝั่ง Rust กับ Zig ไปเป็น CPU ที่เก่ากว่าได้เหมือนกัน ผมไม่ได้นึกถึงข้อจำกัดของ target ฝั่ง JS มาก่อน และตัวอย่าง C++ ก็แสดงให้เห็นว่า clang สร้างโค้ดได้ดีแค่ไหน เพียงแต่ตอนนี้ assembly ก็ยังไม่ได้น่าพอใจนัก (แม้จะคำนึงว่า zig สร้างบิลด์สำหรับ CPU เป้าหมายเฉพาะก็ตาม) ถ้ามีตัวอย่างพอร์ต คอมไพล์ไทม์ Suffix Automaton ไป C++ ด้วยก็น่าสนใจมาก นี่คือกรณีใช้งานจริงของ comptime ที่คอมไพเลอร์ C++ เดาเองไม่ได้
  • ผมสงสัยกับประโยคที่ว่า "ภาษา high-level ขาด 'intent' แบบที่ภาษา low-level มี" ตรงกันข้าม ผมกลับมองว่าจุดเด่นของภาษา high-level คือการแสดงเจตนาอย่างละเอียดได้หลากหลายกว่า
    • ผมก็เห็นด้วย โดยพื้นฐานแล้วความต่างระหว่างภาษา high-level กับ low-level คือ ในภาษา high-level เราแสดงเจตนา ส่วนใน low-level เราจำเป็นต้องเปิดเผยกลไกการทำงานของ implementation เอง
    • คำว่า 'intent' ตรงนี้ไม่ได้หมายถึงเจตนาทางธุรกิจอย่าง "คำนวณภาษีของการซื้อครั้งนี้" แต่ใกล้เคียงกับการบอกคอมพิวเตอร์ให้ทำอะไร เช่น "เลื่อนบิตนี้ไปทางซ้ายสามตำแหน่ง" ตัวอย่างเช่น purchase.calculate_tax().await.map_err(|e| TaxCalculationError { source: e })?; เป็นโค้ดที่เต็มไปด้วยเจตนา แต่คาดเดาไม่ได้เลยว่าสุดท้าย machine code จะออกมาเป็นอย่างไร
  • ผมชอบโมเดล allocator ของ Zig มาก อยากให้ใน Go ใช้สิ่งอย่าง allocator แยกตาม request ได้แทน GC
    • ใน Go ก็ใช่ว่าจะทำ custom allocator กับ arena ไม่ได้ แต่ใช้งานได้แย่มากและใช้ให้ถูกยาก อีกทั้งก็ไม่มีวิธีแสดงหรือบังคับกฎ ownership ในระดับภาษา สุดท้ายก็เหมือนเขียน C ที่ไวยากรณ์ต่างออกไปนิดหน่อย และถ้าไม่มี GC ก็อาจอันตรายยิ่งกว่า C++ เสียอีก
  • ผมเข้าใจที่บอกว่า "ชอบความ verbose ของ Zig" แต่พูดตรง ๆ ว่ามันฟังดูแปลกนิดหน่อย C มีความหลวมอยู่หลายจุด ขณะที่ Zig กลับต้องการ 'annotation noise' เยอะเกินไปในหลายกรณี (โดยเฉพาะการ cast จำนวนเต็มแบบชัดเจนในนิพจน์คณิตศาสตร์) ดู บทความนี้ ประกอบ ด้านประสิทธิภาพ กรณีที่ zig เร็วกว่า c มักเกิดจาก Zig ใช้การตั้งค่า LLVM ที่ aggressive กว่า (-march=native, whole-program optimization ฯลฯ) จริง ๆ แล้วฝั่ง C ก็ใช้ optimization hint อย่าง unreachable ผ่าน language extension ได้ และ Clang ก็ทำ constant folding อย่างดุดันมากเหมือนกัน พูดอีกแบบคือ ความต่างระหว่าง comptime ของ Zig กับ codegen ของ C หลายครั้งมาจากการตั้งค่า optimization ของคอมไพเลอร์ TL;DR: ถ้า C ช้า ให้ตรวจสอบการตั้งค่าคอมไพเลอร์ก่อน เพราะหัวใจของ optimization ยังไงก็เป็น LLVM อยู่ดี
    • ถ้าพูดถึงตัวอย่างเรื่อง cast ผมกลับมองว่าสามารถสร้างฟังก์ชันขึ้นมาห่อการ cast เพื่อเพิ่มทั้งการนำโค้ดกลับมาใช้ใหม่และความชัดเจนของเจตนาได้
      fn signExtendCast(comptime T: type, x: anytype) T {
        const ST = std.meta.Int(.signed, @bitSizeOf(T));
        const SX = std.meta.Int(.signed, @bitSizeOf(@TypeOf(x)));
        return @bitCast(@as(ST, @as(SX, @bitCast(x))));
      }
      export fn addi8(addr: u16, offset: u8) u16 {
        return addr +% signExtendCast(u16, offset);
      }
      
      วิธีนี้ก็ยังได้ assembly แบบเดียวกัน ใช้งานต่อยอดได้ดี และชัดเจนกว่า
    • ไอเดียของ Zig น่าสนใจ และให้ความสำคัญกับ comptime และการคอมไพล์ทั้งโปรแกรมมากกว่าที่ผมคาดจากบทความต้นฉบับ ตรงนี้ผมเห็นด้วย อ้างอิงเพิ่มคือ Virgil รองรับการใช้ทั้งภาษาใน compile time และการคอมไพล์ทั้งโปรแกรมมาตั้งแต่ปี 2006 แล้ว Virgil ไม่ได้ target ไปที่ LLVM ดังนั้นการเปรียบเทียบความเร็วจึงสุดท้ายเป็นการเทียบ backend Virgil ใช้แนวทางนี้เพื่อทำ optimization ที่แรงมากได้ เช่น devirtualize การเรียกเมธอดล่วงหน้า, ตัด field/อ็อบเจ็กต์ที่ไม่ถูกใช้ออกให้มากที่สุด, propagate ค่าคงที่ไปถึง field-heap object, และ specialize ได้อย่างสมบูรณ์
    • เมื่อมองไปถึงการใช้ AI ในอนาคต ผมคิดว่าภาษาที่ explicit และ verbose มากขึ้นจะยิ่งกลายเป็นกระแสหลัก ไม่ว่าจะเขียนโค้ดด้วย AI หรือการทำแบบนั้นถูกต้องหรือไม่ก็ตาม นักพัฒนาจำนวนมากจะชอบมี AI ช่วยมากขึ้น และภาษาก็จะเปลี่ยนไปให้เข้ากับสิ่งนั้น
    • ถ้ามี x86 backend ตัวใหม่เข้ามา ในอนาคตก็น่าจะได้เห็นกรณีที่ความต่างด้านประสิทธิภาพระหว่าง C กับ Zig มาจากตัวโปรเจกต์ Zig เองด้วย
    • เรื่อง integer cast แบบ explicit มีการปรับปรุงที่น่าจะทำให้สะอาดขึ้นในเร็ว ๆ นี้ ดู การพูดคุยที่เกี่ยวข้อง
  • ถึงจะไม่ถูกต้องนักที่จะ benchmark ว่า "C เร็วกว่า Python" แบบเหมารวมทั้งภาษา แต่บางฟีเจอร์ของภาษาก็เป็นกำแพงต่อ optimization ได้มากจริง ๆ ถ้าใช้ภาษาที่เหมาะสม ทั้งนักพัฒนาและคอมไพเลอร์ก็จะสามารถแสดงเจตนาในรูปแบบที่เป็นธรรมชาติและเร็วได้
  • ผมรู้สึกว่าไวยากรณ์ for loop ของ Zig ดูรกรุงรังเกินไป ต้องเอาลิสต์สองชุดมาวางขนานกันและจัดตำแหน่งให้ตรงกัน แค่มองก็ปวดตาแล้ว ผมคิดว่าภาษายุคหลัง ๆ พลาดตรงที่ยัด syntax แบบ 'เวทมนตร์' และสัญลักษณ์พิเศษมากเกินไป ดูแล้วคงทนจ้องหลายชั่วโมงไม่ไหว
    • รูปแบบการวนผ่านอาร์เรย์สองชุดแบบนี้พบได้บ่อยมากในโค้ด low-level และการวนแบบขนานก็เช่นกัน ดังนั้นที่ Zig รองรับสิ่งนี้อย่างชัดเจนและเป็นธรรมชาติจึงกลับดูเหมาะสมดี ผมสงสัยว่าทำไมมันถึงทำให้ปวดตา
  • optimization สำคัญมาก และผลของมันจะยิ่งมากขึ้นเรื่อย ๆ เมื่อเวลาผ่านไป
    • แต่ก็เป็นจริงก็ต่อเมื่อซอฟต์แวร์นั้นถูกนำไปใช้งานจริงเท่านั้น