ทำไมไพ ธ อนจึงต้องการทั้งคอมไพเลอร์และล่าม


9

ฉันเข้าใจความจริงที่ว่า Java ต้องการทั้งคอมไพเลอร์และล่าม มันรวบรวมซอร์สโค้ดเป็น bytecode จากนั้นเครื่องเสมือน (บน Windows, Linux, Android ฯลฯ ) แปลว่า bytecode เป็นรหัสเครื่องสำหรับสถาปัตยกรรมปัจจุบัน

แต่ทำไมไพ ธ อนจึงต้องการทั้งคอมไพเลอร์และล่าม เนื่องจาก Python ไม่ได้ขึ้นกับแพลตฟอร์มทำไมไม่ใช้แค่การตีความ? เท่าที่ฉันรู้คุณไม่สามารถรันโปรแกรม Python (เรียบเรียงเป็น bytecode) บนเครื่อง Windows หรือ Linux ใด ๆ โดยไม่มีการดัดแปลง หรือฉันผิด


คุณอาจผิด หากใช้ Lua แทน Python คุณจะผิด
Basile Starynkevitch

คำตอบ:


13

เท่าที่ฉันรู้คุณไม่สามารถรันโปรแกรม Python (เรียบเรียงเป็น bytecode) ในทุกเครื่องเช่นใน windows หรือบน linux โดยไม่มีการดัดแปลง

คุณไม่ถูกต้อง python bytecode เป็นแพลตฟอร์มข้าม ดูpython bytecode ขึ้นอยู่กับรุ่นหรือไม่ มันขึ้นอยู่กับแพลตฟอร์มหรือไม่ บน Stack Overflow อย่างไรก็ตามมันเข้ากันไม่ได้กับทุกเวอร์ชั่น Python 2.6 ไม่สามารถเรียกใช้งานไฟล์ Python 2.5 ดังนั้นในขณะที่ข้ามแพลตฟอร์มมันไม่ได้มีประโยชน์โดยทั่วไปว่าเป็นรูปแบบการกระจาย

แต่ทำไมหลามถึงต้องการคอมไพเลอร์และล่าม

ความเร็ว. การตีความที่เข้มงวดช้า แทบทุกภาษา "ตีความ" แปลคอมไพล์ซอร์สโค้ดในรูปแบบของการเป็นตัวแทนภายในเพื่อที่จะได้ไม่ต้องแยกวิเคราะห์รหัสซ้ำ ๆ ในกรณีของงูหลามมันจะบันทึกการเป็นตัวแทนภายในลงในดิสก์เพื่อให้สามารถข้ามกระบวนการแยกวิเคราะห์ / รวบรวมในครั้งต่อไปที่มันต้องการรหัส


7

ฉันเข้าใจความจริงที่ว่า Java ต้องการทั้งคอมไพเลอร์และล่าม

มันไม่ได้ ไม่มีสิ่งใดใน Java Language Specification ที่บอกว่า Java ต้องมีคอมไพเลอร์ ไม่มีอะไรใน Java Language Specification ที่บอกว่า Java ต้องมีล่าม

ไม่ว่าจะใช้ล่ามคอมไพเลอร์หรือการรวมกันของทั้งสองนั้นจะขึ้นอยู่กับดุลยพินิจของผู้ดำเนินการ

ในความเป็นจริงมีอยู่การใช้งาน Java ซึ่งรวบรวมตรงไปที่รหัสเครื่องเช่นแอฟริกาคอมไพเลอร์สำหรับ gcjJava ในทางเทคนิคแล้วคอมไพเลอร์ Oracle OpenJDK Java ยังรวบรวมไปยังรหัสเครื่องโดยเฉพาะรหัสไบต์ JVM ตอนนี้คุณอาจพูดว่าเดี๋ยวก่อนนั่นไม่ใช่รหัสเครื่อง! แต่มีล่ามซอฟต์แวร์สำหรับรหัสเครื่อง x86 และมีซีพียูฮาร์ดแวร์ที่สามารถเรียกใช้โค้ดไบต์ JVM ดังนั้นสิ่งที่ทำให้ "พื้นเมือง" และอื่น ๆ ไม่ได้?

โปรดทราบว่าโค้ดไบต์ JVM อยู่นอกข้อกำหนดภาษา Java เช่นเดียวกับรหัสเครื่อง x86

จากนั้นเครื่องเสมือน (บน Windows, Linux, Android ฯลฯ ) แปลว่า bytecode เป็นรหัสเครื่องสำหรับสถาปัตยกรรมปัจจุบัน

อีกครั้งนั่นขึ้นอยู่กับผู้ดำเนินการ

Sun JVM ดั้งเดิมไม่เคยแปลมันตีความอยู่เสมอ Oracle OpenJDK JVM ปัจจุบันตีความและเฉพาะส่วนที่ได้รับการดำเนินการมักจะรวบรวม Maxine Research VM รวบรวม JIT เสมอ การปรับใช้ Excelsior.JET รวบรวมหนึ่งครั้งล่วงหน้า IKVM.NET JVM คอมไพล์รหัส CIL ไบต์ Android Runtime คอมไพล์ล่วงหน้าเวลาหนึ่งครั้งระหว่างการติดตั้ง (นอกจากนี้ Android Runtime ไม่เข้าใจรหัส JVM ไบต์ใช้รหัส Dalvik ซึ่งเป็นภาษาที่แตกต่างอย่างสิ้นเชิง)

แต่ทำไมไพ ธ อนจึงต้องการทั้งคอมไพเลอร์และล่าม

อีกครั้งมันไม่ ไม่มีอะไรใน Python Language Specification ที่บอกว่า Python จำเป็นต้องมีคอมไพเลอร์ นอกจากนี้ยังไม่มีอะไรใน Python Language Specification ที่บอกว่า Python จำเป็นต้องมีล่าม

โปรดทราบว่าจริงๆแล้ว Python ไม่เคยตีความ ทั้งหมดที่มีอยู่ในการดำเนินการหลามเสมอรวบรวมงูใหญ่ให้เป็นภาษาที่แตกต่างกัน ภาษานั้นอาจตีความได้บ้างหรือไม่ก็ได้ แต่ภาษานั้นเป็นภาษาอื่นจาก Python Python ไม่ได้รับการตีความ

ทำไมไม่ใช้แค่การตีความ?

เพราะ Python ไม่ได้ออกแบบมาให้ตีความได้ง่ายโดยเครื่อง มันถูกออกแบบมาให้ตีความได้ง่ายโดยมนุษย์ OTOH, โค้ดไบต์ CPython ถูกออกแบบมาให้ตีความได้ง่ายโดยเครื่อง ดังนั้นจึงเหมาะสมที่จะเขียนโค้ดในภาษาที่ออกแบบมาสำหรับมนุษย์และตีความในภาษาที่ออกแบบมาสำหรับเครื่องจักรและเพื่อให้ได้จากสิ่งหนึ่งไปอีกสิ่งหนึ่ง

เท่าที่ฉันรู้คุณไม่สามารถรันโปรแกรม Python (เรียบเรียงเป็น bytecode) บนเครื่อง Windows หรือ Linux ใด ๆ โดยไม่มีการดัดแปลง

ใช่คุณสามารถ. CPython VM พร้อมใช้งานสำหรับทั้ง Windows และ Linux เช่นเดียวกับ PyPy, Jython และ IronPython


ภาษาไม่จำเป็นต้องรวบรวมหรือตีความ ภาษาเพียงแค่มี ในความเป็นจริงภาษาที่ดีที่สุดที่สามารถอยู่ได้โดยไม่ต้องใด ๆล่ามหรือคอมไพเลอร์! ตัวอย่างเช่นPlankalkülของ Konrad Zuse ซึ่งเขาออกแบบในช่วงทศวรรษที่ 1930 ไม่เคยถูกนำมาใช้ในช่วงชีวิตของเขา คุณยังคงสามารถเขียนโปรแกรมในนั้นคุณสามารถวิเคราะห์โปรแกรมเหล่านั้นให้เหตุผลเกี่ยวกับพวกเขาพิสูจน์คุณสมบัติเกี่ยวกับพวกเขา ... คุณไม่สามารถดำเนินการได้ (ที่จริงแล้วแม้จะเป็นความผิด: แน่นอนคุณสามารถเรียกใช้พวกเขาในหัวของคุณหรือด้วยปากกาและกระดาษ)

ตอนนี้การใช้ภาษาใด ๆ โดยเฉพาะอาจใช้คอมไพเลอร์ (หรือแม้แต่คอมไพเลอร์หลายตัว), ล่ามหรือชุดค่าผสม แต่นั่นเป็นลักษณะของการใช้งานไม่ใช่ภาษา ทุกภาษาสามารถนำไปใช้กับคอมไพเลอร์และทุกภาษาสามารถนำไปใช้กับล่าม

อย่างไรก็ตามโปรดทราบว่าคุณไม่สามารถเรียกใช้โปรแกรมได้หากไม่มีล่าม คอมไพเลอร์แปลโปรแกรมจากภาษาหนึ่งเป็นอีกภาษาหนึ่ง แต่นั่นมัน ตอนนี้คุณมีโปรแกรมเดียวกันในภาษาอื่น เพียงวิธีการที่จะได้รับจริงเป็นผลมาจากโครงการคือการแปลความหมายของมัน บางครั้งภาษานั้นเป็นภาษาเครื่องไบนารีที่ง่ายมากและล่ามนั้นจะถูกฮาร์ดโค้ดในซิลิโคน (และเราเรียกมันว่า "CPU") แต่นั่นก็ยังเป็นการตีความ

นอกจากนี้คุณยังอาจจะสนใจในคำตอบนี้ของฉันซึ่งจะอธิบายความแตกต่างและวิธีการที่แตกต่างกันของการรวมล่ามคอมไพเลอร์ JIT และคอมไพเลอร์ทอทและคำตอบนี้จัดการกับความแตกต่างระหว่างคอมไพเลอร์และทอทคอมไพเลอร์ JIT ที่


3
คำตอบที่ใช้เวลาส่วนใหญ่เป็นคนอวดดีแทนที่จะตอบคำถามทำให้ฉันเศร้า
Winston Ewert

3

มันเป็นความจริงที่ bytecode ไม่เหมาะกับรูปแบบการกระจาย แต่นั่นไม่ได้หมายความว่ามันไร้ประโยชน์ นอกเหนือจากการปรับปรุงเวลาเริ่มต้นบนเครื่องที่กำหนดหลังจากการเรียกใช้ครั้งแรกการตีความ bytecode ยังง่ายกว่าการตีความ AST หรือการห้ามพระเจ้าการตีความแบบบรรทัดต่อบรรทัด

Bytecode เป็นการนำเสนอรหัสในระดับต่ำกว่าปกติมากขึ้นกะทัดรัดมากขึ้น (ทั้งความหมายและในแง่ของรูปแบบหน่วยความจำ) ลำดับของการดำเนินการได้ถูกสะกดออกไปแล้วชื่อตัวแปรท้องถิ่นได้รับการแก้ไขในรูปแบบที่ง่ายขึ้น (ดัชนีจำนวนเต็ม) ไม่มีไวยากรณ์ที่ซับซ้อนในการติดตามเพียงแค่หนึ่งคำสั่งง่ายๆหลังจากนั้นอีก นอกจากนี้จำเป็นต้องมีสถานะน้อยลง: สำหรับการตีความแบบบรรทัดต่อบรรทัดโดยทั่วไปคุณจำเป็นต้องใช้เครื่องมือแยกวิเคราะห์ทั้งหมดและ AST interpreter จะระเบิด call stack ด้วย traversal ของต้นไม้ในขณะที่ล่าม bytecode ต้องการสแต็กขนาดเล็กสำหรับค่าชั่วคราว และคนในท้องถิ่น

ปัจจัยเหล่านี้และปัจจัยอื่น ๆ สมคบกันที่จะทำให้ล่าม bytecode เร็วกว่าล่ามคนอื่นอย่างมาก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.