- การแจกจ่ายเครื่องมือเป็น ไบนารีแบบสแตติกที่รันได้ด้วยตัวเอง ทำให้ผู้ใช้สามารถใช้งานได้ทันทีโดยไม่ต้อง ติดตั้งสภาพแวดล้อมการพัฒนาหรือ toolchain เพิ่มเติม
- กระบวนการคอมไพล์ทำหน้าที่เป็น ชั้นป้องกันเพิ่มเติม ที่ช่วยลดโอกาสในการ ปล่อยโค้ดที่ทำงานผิดปกติ
- เครื่องมือที่สร้างบนภาษาแบบอินเทอร์พรีเตอร์มีภาระในการดูแลรักษาสูง ทั้งเรื่อง การติดตั้ง dependency จำนวนมากและการสิ้นเปลืองพื้นที่ดิสก์, รวมถึง การติดตั้งซ้ำเมื่ออัปเกรด
- ยิ่งมี dependency มากเท่าไร ก็ยิ่งเพิ่ม ช่องโหว่ด้านความปลอดภัย และ พื้นที่ผิวการโจมตี ทำให้มีความเสี่ยงต่อการถูกโจมตีหรือเกิดปัญหาด้านการบำรุงรักษาได้ง่ายขึ้น
- ไบนารีแบบสแตติกที่สร้างจากภาษาคอมไพล์ ไม่ได้รับผลกระทบจากการเปลี่ยนแปลงของสภาพแวดล้อมภายนอก จึงรับประกัน ความเสถียรในการใช้งาน ได้แม้หลังการแจกจ่าย
ข้อดีของการแจกจ่ายแบบไบนารีสแตติกที่ทำงานได้ด้วยตัวเอง
ใช้งานได้ทันทีโดยไม่ต้องติดตั้ง
- เช่นกรณีที่ Open AI สร้าง Codex ใหม่ด้วย Rust และเลิกใช้ TypeScript หากแจกจ่าย ไบนารีเดี่ยวที่เขียนด้วยภาษาคอมไพล์ ผู้ใช้ก็สามารถรันได้ทันทีโดยไม่ต้องติดตั้ง toolchain เพิ่มเติม
- ข้อดีที่สำคัญที่สุดไม่ใช่เรื่องความเร็วหรือประสิทธิภาพ แต่คือ สามารถใช้เครื่องมือได้ทันทีโดยไม่ต้องติดตั้ง
คอมไพเลอร์เป็นชั้นป้องกันเพิ่มเติม
- การตรวจสอบในขั้นตอนคอมไพล์ช่วยลดโอกาสในการ แจกจ่ายโค้ดที่ผิดปกติ
- ตัวอย่างเช่น Google Cloud CLI ซึ่งพัฒนาด้วย Python เคยถูก ปล่อยออกมาในสถานะที่ใช้งานไม่ได้ หลายครั้ง
- แม้แต่ทีมขนาดใหญ่ก็ยังหลีกเลี่ยงปัญหานี้ได้ยาก และสำหรับทีมขนาดเล็ก การแจกจ่ายเครื่องมือที่สร้างบนภาษาแบบอินเทอร์พรีเตอร์ให้เสถียรนั้นยิ่งยากกว่า
ไม่จำเป็นต้องพึ่งพา toolchain
- เครื่องมือที่สร้างด้วยภาษาคอมไพล์ แจกจ่ายเพียงไบนารีเดี่ยวก็เพียงพอ แต่ เครื่องมือบนภาษาแบบอินเทอร์พรีเตอร์ เช่น Python, Ruby, TypeScript จำเป็นต้องมีสภาพแวดล้อมการพัฒนานั้น ๆ เสมอ
- เช่น mdl (markdown linter) ที่เขียนด้วย Ruby จะต้องติดตั้งใหม่ทุกครั้งเมื่อมีการอัปเกรดสภาพแวดล้อมการพัฒนา (Ruby)
- หากใช้ markdownlint ที่พัฒนาด้วย JavaScript ก็ต้องติดตั้ง npm และ dependency มากกว่า 44 รายการ
ปัญหาการสิ้นเปลืองพื้นที่ดิสก์
- aider ผู้ช่วยเขียนโค้ด FOSS ยอดนิยมถูกเขียนด้วย Python และเมื่อติดตั้งผ่าน Homebrew จะมี แพ็กเกจเพิ่มเติมอีก 51 รายการ ถูกติดตั้งตามมา
- การใช้พื้นที่ดิสก์จริงเพิ่มขึ้นมากกว่า 3GiB ซึ่งมากกว่าขนาดของลินุกซ์ดิสทริบิวชันส่วนใหญ่เสียอีก
- ในทางกลับกัน uv package manager ที่เขียนด้วย Rust สามารถติดตั้งได้ด้วย ไบนารีเดี่ยวขนาด 35MiB โดยไม่ต้องมี Rust เองหรือ rustup
ช่องโหว่ด้านความปลอดภัยที่เพิ่มขึ้น
- ยิ่งเครื่องมือมี dependency มากขึ้น ก็ยิ่งขยายพื้นที่ผิวการโจมตี และเพิ่มโอกาสในการเผชิญกับช่องโหว่ด้านความปลอดภัย
- แพ็กเกจ Codex ของ OpenAI มี dependency ทางตรง 24 รายการ และทางอ้อม 184 รายการ
- ต่อให้ OpenAI ตรวจสอบ dependency ทั้งหมดแล้วก็ตาม หากไม่ได้ตรึงเวอร์ชัน dependency ไว้ ก็ยังอาจเกิดปัญหาอย่าง ช่องโหว่, แพ็กเกจอันตราย, หรือการทำงานหยุดชะงัก จากการอัปเดตในอนาคตได้
ความง่ายในการบำรุงรักษา
- เครื่องมือที่อยู่บนภาษาแบบอินเทอร์พรีเตอร์ เช่น JavaScript, TypeScript, Python จะ ไม่สามารถทำงานได้หาก dependency ถูกลบออก
- ดังเช่นเหตุการณ์ left-pad ที่การลบแพ็กเกจเพียงตัวเดียวสามารถทำให้บริการและเครื่องมือจำนวนมากใช้งานไม่ได้
- ภาษาคอมไพล์ต้องพึ่งพา dependency เฉพาะตอน build เท่านั้น ดังนั้นแม้ repository ภายนอกจะหายไปในภายหลัง เครื่องมือก็ยังคงทำงานได้ตามปกติ
ประสบการณ์ของผู้เขียน
- ผู้เขียนเคยสร้างเครื่องมืออย่าง adb-enhanced ด้วย Python มาก่อน และต่อมาก็โอเพนซอร์สเครื่องมือต่าง ๆ เช่น gabo, wp2hugo ด้วย Go
- ปัจจุบัน ไม่พิจารณาการพัฒนาเครื่องมือแบบสแตนด์อโลนด้วย Python หรือ TypeScript อีกต่อไป
- แนะนำอย่างยิ่งให้ใช้ ภาษาที่สามารถแจกจ่ายไบนารีแบบลิงก์สแตติกได้ (Rust, Go, C++ ฯลฯ)
บทสรุป
- เครื่องมือแบบสแตนด์อโลนควรพัฒนาด้วยภาษาคอมไพล์อย่าง Rust, Go, C++
- ควรแจกจ่ายในรูปแบบ ไบนารีสแตติก ที่มี dependency ภายนอกให้น้อยที่สุด
3 ความคิดเห็น
ผมเห็นด้วยกับประเด็น
ปัญหาการสิ้นเปลืองพื้นที่ดิสก์อยู่ไม่น้อยเลยครับ...ผมดูแล AKS อยู่ แล้วทุกครั้งที่เห็นแอป Python ที่มีขนาดอิมเมจคอนเทนเนอร์เกิน 1GB ก็ปวดหัวมากครับ
ตอนนี้ก็แค่เอา Dockerfile มาปรับเองเพื่อลดขนาดแล้วอัปขึ้นไปใหม่ ถ้าลดให้ต่ำกว่า 500MB ไม่ได้ก็ยอมแพ้เลยครับ 555
มีแพ็กเกจที่ผูก dependency ของ
pytorch+cudaไว้โดยต่างกันแค่เวอร์ชัน... ชวนปวดหัวมากทั้งที่แทบไม่มีฟีเจอร์อะไรเลย แต่เดมอนเล็ก ๆ แต่ละตัวกลับต้องติดตั้ง dependency เกือบ 2GB..
ถ้าเป็น CPU runtime ที่ใช้แค่สำหรับงานอนุมานแบบง่าย ๆ สถานการณ์ก็ยังพอไหวอยู่บ้าง แต่พอมีบริการ LLM ที่สมัยนี้ต้องรองรับกัน ทั้งทราฟฟิกก็พุ่ง ขนาดระบบก็โต ค่าใช้จ่ายตอนคำนวณนี่แทบสบถออกมาเลย 555