คอมไพเลอร์ Just-In-Time (JIT) แบบทดลองของ Python ได้เจออุปสรรคสำคัญ หลังจากพัฒนามา 2 ปี JIT มักจะทำงานช้ากว่า interpreter ปกติของ Python ทำให้เกิดคำถามเกี่ยวกับทิศทางอนาคตของโครงการและเน้นย้ำถึงความท้าทายในการเพิ่มประสิทธิภาพของภาษาโปรแกรมมิ่งแบบไดนามิก
โครงการ CPython JIT เริ่มต้นด้วยความหวังสูงที่จะเพิ่มความเร็วในการรันโค้ด Python อย่างมีนัยสำคัญ อย่างไรก็ตาม การวิเคราะห์ล่าสุดแสดงให้เห็นว่าเมื่อใช้คอมไพเลอร์สมัยใหม่อย่าง Clang 20 interpreter จะมีประสิทธิภาพดีกว่า JIT อย่างสม่ำเสมอ JIT จะเทียบเท่าได้เฉพาะเมื่อ interpreter ถูกจำกัดความสามารถโดยการใช้คอมไพเลอร์เก่าที่มีประสิทธิภาพต่ำกว่าอย่าง GCC 11
ไทม์ไลน์การพัฒนา CPython JIT
- 2022-2023: การพัฒนา JIT เริ่มต้นขึ้น
- Python 3.13: JIT ถูกเปิดตัวในรูปแบบฟีเจอร์ทดลอง ซึ่งมักจะช้ากว่า interpreter
- Python 3.14: มุ่งเน้นไปที่การขยายการวิเคราะห์ประเภทข้อมูลและการสร้างชุมชน โดยมีการปรับปรุง optimizer เพียงเล็กน้อย
- Python 3.15+: การปรับปรุงที่วางแผนไว้ประกอบด้วย int/float unboxing, การปรับปรุง register allocation, การรองรับ free-threading
![]() |
---|
บล็อกโพสต์นี้สะท้อนถึงปัญหาด้านประสิทธิภาพและบทเรียนที่ได้เรียนรู้จากการพัฒนา CPython JIT compiler เป็นเวลาสองปี |
การตรวจสอบประสิทธิภาพที่เป็นจริง
ตัวเลขต่างๆ เล่าเรื่องราวที่น่าเศร้า ในการทดสอบ benchmark JIT แสดงผลลัพธ์ที่หลากหลายซึ่งขัดแย้งกับรายงานในแง่บวกในช่วงแรก ในขณะที่งานบางประเภทอย่าง Richards benchmark เห็นการปรับปรุงความเร็วขึ้น 15% แต่งานอื่นๆ กลับประสบกับการชะลอตัวอย่างมีนัยสำคัญ ตัวอย่างเช่น nbody benchmark ทำงานช้าลง 13% เมื่อเปิดใช้งาน JIT และ spectral_norm แสดงการลดลงของประสิทธิภาพ 6%
ประสิทธิภาพที่ไม่สม่ำเสมอนี้เกิดจากข้อจำกัดปัจจุบันของ JIT เวอร์ชัน 3.14 มีการปรับปรุง optimizer หลักเกือบไม่มีเลยเมื่อเทียบกับรุ่น 3.13 แต่มุ่งเน้นไปที่การขยายความครอบคลุมของการวิเคราะห์ประเภทและการสร้างความเชี่ยวชาญของผู้ร่วมพัฒนาแทน ทีมพัฒนาให้ความสำคัญกับการสร้างชุมชนและการถ่ายทอดความรู้มากกว่าการเพิ่มประสิทธิภาพในทันที
การเปรียบเทียบ Performance Benchmark ( CPython 3.14 )
Benchmark | JIT ปิด | JIT เปิด | การเปลี่ยนแปลงประสิทธิภาพ |
---|---|---|---|
Richards | 44.5ms ± 0.5ms | 37.8ms ± 2.4ms | เร็วขึ้น +15% |
Nbody | 91.8ms ± 3.5ms | 104ms ± 2ms | ช้าลง -13% |
Spectral_norm | 90.6ms ± 0.7ms | 96.0ms ± 0.7ms | ช้าลง -6% |
การกำหนดค่าการทดสอบ: Ubuntu 22.04 , Clang 20.1.7 , PGO=true, LTO=thin
ความท้าทายของภาษาไดนามิก
Python เผชิญกับอุปสรรคการเพิ่มประสิทธิภาพที่เป็นเอกลักษณ์เมื่อเปรียบเทียบกับภาษาไดนามิกอื่นๆ การอภิปรายในชุมชนเผยให้เห็นว่าโมเดลออบเจ็กต์ของ Python ซึ่งมักถูกอธิบายว่าทุกอย่างคือ dict ที่มี string keys สร้างอุปสรรคด้านประสิทธิภาพขั้นพื้นฐาน ไม่เหมือนกับ JavaScript ที่ได้รับประโยชน์จากการลงทุนขนาดใหญ่ของบริษัทและการตัดสินใจในการออกแบบที่เอื้อต่อการเพิ่มประสิทธิภาพ สถาปัตยกรรมของ Python ทำให้การคอมไพล์ JIT เป็นเรื่องที่ท้าทายเป็นพิเศษ
การเปรียบเทียบกับคอมไพเลอร์ YJIT ของ Ruby นั้นน่าสนใจเป็นพิเศษ Ruby ประสบความสำเร็จในการปรับปรุงประสิทธิภาพอย่างมีนัยสำคัญด้วยทีมที่เล็กกว่า ส่วนหนึ่งเป็นเพราะความหมายของ Ruby สอดคล้องกับเทคนิคการเพิ่มประสิทธิภาพ JIT ที่มีอยู่แล้วซึ่งพัฒนาสำหรับภาษาอย่าง Smalltalk C API ที่กว้างขวางของ Python และความมุ่งมั่นในการรักษาความเข้ากันได้แบบย้อนหลังยิ่งทำให้ความพยายามในการเพิ่มประสิทธิภาพซับซ้อนมากขึ้น
โมเดลออบเจ็กต์ภายในหนักเกินไปในสภาพปัจจุบัน ดังนั้นการกำจัดประเภทของค่าใช้จ่ายที่ JIT กำจัดจะไม่ช่วยได้เนื่องจากนั่นไม่ใช่สิ่งที่ CPU ใช้เวลามากเมื่อรัน CPython
การพัฒนาแบบชุมชนเทียบกับบริษัท
การต่อสู้ของโครงการเน้นย้ำถึงความท้าทายที่กว้างขวางในการเพิ่มประสิทธิภาพแบบโอเพ่นซอร์ส ในขณะที่ Google ลงทุนทรัพยากรมหาศาลเพื่อทำให้ JavaScript เร็วผ่าน V8 และ Shopify สนับสนุนการพัฒนา YJIT ของ Ruby ได้สำเร็จ JIT ของ Python พึ่งพาอาสาสมัครชุมชนและการสนับสนุนจากบริษัทที่จำกัดเป็นหลัก ทีม Faster CPython ของ Microsoft ซึ่งให้การสนับสนุนอย่างมีนัยสำคัญ เผชิญกับการเลิกจ้างที่ลดความเชี่ยวชาญที่มีอยู่
ทีมพัฒนายอมรับความท้าทายเหล่านี้ในขณะที่ยังคงมองโลกในแง่ดีเกี่ยวกับการปรับปรุงในอนาคต พวกเขาสร้างชุมชนผู้ร่วมพัฒนารอบ JIT ได้สำเร็จ โดยมีนักพัฒนาหลายคนทำงานในส่วนประกอบต่างๆ ในขณะนี้ แนวทางที่ขับเคลื่อนโดยชุมชนนี้ให้ความสำคัญกับความยั่งยืนระยะยาวมากกว่าการเพิ่มประสิทธิภาพในทันที
มองไปข้างหน้า
แม้จะมีข้อจำกัดในปัจจุบัน CPython JIT ยังไม่พร้อมที่จะเกษียณ ทีมได้ระบุโอกาสการเพิ่มประสิทธิภาพหลายประการที่สามารถส่งมอบการเพิ่มความเร็วที่มีความหมายใน Python 3.15 ซึ่งรวมถึง integer และ float unboxing การจัดสรร register ที่ชาญฉลาดกว่า และการรวมที่ดีกว่ากับการสนับสนุน free-threading ของ Python
โครงการนี้ทำหน้าที่เป็นประสบการณ์การเรียนรู้ที่มีค่าเกี่ยวกับความซับซ้อนของการเพิ่มประสิทธิภาพภาษาไดนามิก แม้ว่าเป้าหมายด้านประสิทธิภาพจะยังคงเข้าใจยาก แต่ JIT ได้กลายเป็นเครื่องมือการศึกษาที่ช่วยให้ผู้เริ่มต้นเข้าใจเทคนิคการเพิ่มประสิทธิภาพคอมไพเลอร์ ว่าคุณค่าทางการศึกษานี้สมควรกับการลงทุนอย่างต่อเนื่องหรือไม่ยังคงเป็นคำถามเปิดในขณะที่ชุมชน Python ชั่งน้ำหนักต้นทุนและประโยชน์ของการติดตาม JIT compilation
เรื่องราวของ CPython JIT แสดงให้เห็นว่าการทำให้ภาษาไดนามิกเร็วต้องการมากกว่าความตั้งใจดีและทักษะทางเทคนิค มันต้องการการตัดสินใจทางสถาปัตยกรรมขั้นพื้นฐาน ทรัพยากรที่เพียงพอ และบางครั้งการแลกเปลี่ยนที่ยากลำบากระหว่างความเข้ากันได้และประสิทธิภาพ
อ้างอิง: Reflections on 2 years of CPython's JIT Compiler: The good, the bad, the ugly