Python ตีความหรือเรียบเรียงหรือไม่?


76

นี่เป็นเพียงความสงสัยในขณะที่ฉันอ่านเกี่ยวกับภาษาที่แปลและเรียบเรียง

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

ตอนนี้มาที่Python :

  • รหัสหลาม ( somefile.py ) เมื่อนำเข้าสร้างไฟล์ ( somefile.pyc ) ในไดเรกทอรีเดียวกัน ให้เราบอกว่าการนำเข้าจะทำในเปลือกหลามหรือโมดูล django หลังจากนำเข้าฉันเปลี่ยนรหัสเล็กน้อยและดำเนินการฟังก์ชั่นที่นำเข้าอีกครั้งเพื่อค้นหาว่ามันยังคงใช้รหัสเดิมอยู่ สิ่งนี้ชี้ให้เห็นว่าไฟล์ * .pyc เป็นไฟล์ไพ ธ อนที่คอมไพล์เหมือนกับไฟล์ที่สร้างขึ้นหลังจากการคอมไพล์ไฟล์ C ถึงแม้ว่าฉันจะไม่สามารถเรียกใช้ไฟล์ * .pyc ได้โดยตรง
  • เมื่อดำเนินการไฟล์ python (somefile.py) โดยตรง (./somefile.py หรือ python somefile.py) จะไม่มีการสร้างไฟล์. pyc และรหัสจะถูกดำเนินการตามที่ระบุถึงพฤติกรรมที่ตีความ

สิ่งเหล่านี้แนะนำให้รวบรวมรหัสไพ ธ อนทุกครั้งที่มีการนำเข้าในกระบวนการใหม่เพื่อสร้าง. pyc ในขณะที่มันถูกตีความเมื่อดำเนินการโดยตรง

ดังนั้นฉันควรใช้ภาษาประเภทใด ตีความหรือรวบรวม? และประสิทธิภาพของมันเปรียบเทียบกับภาษาที่แปลและเรียบเรียงได้อย่างไร

ตามที่หน้าภาษาตีความของวิกินั้นมีการระบุว่าเป็นภาษาที่คอมไพล์ด้วยรหัสเครื่องเสมือนจริงนั่นหมายความว่าอย่างไร


1
เมื่อใดที่มีข้อสงสัยว่าทับทิมเป็นภาษาตีความหรือไม่ เมื่อรวบรวมแล้ว :) macruby.org
mipadi

8
เป็นที่น่าสังเกตว่าไม่มีการตีความภาษาสมัยใหม่อย่างเข้มงวด แทบทั้งหมดรวบรวมโดย bytecode
Winston Ewert

@Winston Ewert: bravo! Applesoft Basic (ในปี 1980) ได้รวบรวมรหัสไบต์ "ทันสมัย" ในกรณีนี้หมายถึงทุกภาษาที่ถูกตีความในความทรงจำในการดำรงชีวิตโดยมีข้อยกเว้นเพียงอย่างเดียวคือการใช้งานพื้นฐานของดาร์ทเมาท์เบื้องต้น
S.Lott

6
>> ในทางตรงกันข้าม C เป็นภาษาที่คอมไพล์ << root.cern.ch/drupal/content/cint
igouy

3
@ S.Lott: การเรียกใช้กระบวนการโทเค็นที่ Applesoft และ '80s ล่ามพื้นฐานได้ "การรวบรวม bytecode" เป็นมากกว่าการมีเลศนัยเล็กน้อย ใช่รหัสโปรแกรมที่ป้อนโดยผู้ที่ถูกเก็บไว้ในหน่วยความจำในรูปแบบการบีบอัดหนึ่งไบต์ต่อคำสงวน RUNแต่ไม่มีอะไรที่ได้กระทำเกินกว่าที่จนกว่าคุณพิมพ์ ราวกับว่าคุณมีคอมไพเลอร์ที่ทำตามขั้นตอนที่ยุ่งยากแล้วส่งสัญญาณของโทเค็นที่ต้องทำการวิเคราะห์ใหม่ทุกครั้งที่โปรแกรมทำงาน ไม่เหมือนการรวบรวม bytecode ที่ทันสมัยเช่นเดียวกับที่ทำโดยพูดjavacซึ่งรวมถึง lexing, parsing และการเพิ่มประสิทธิภาพ
dodgethesteamroller

คำตอบ:


80

เป็นที่น่าสังเกตว่าภาษานั้นไม่ได้แปลหรือเรียบเรียง แต่เป็นการประยุกต์ใช้ภาษาอย่างใดอย่างหนึ่งแปลความหมายหรือรวบรวมรหัส คุณสังเกตว่า Ruby เป็น "ภาษาที่ตีความ" แต่คุณสามารถรวบรวม Ruby à la MacRubyได้ดังนั้นจึงไม่ใช่ภาษาที่ตีความเสมอไป

การใช้งาน Python ทุกครั้งนั้นประกอบไปด้วยล่าม (แทนที่จะเป็นผู้แปล) .pycไฟล์ที่คุณเห็นเป็นรหัสไบต์สำหรับเครื่องเสมือนงูหลาม (คล้ายกับของ Java .classไฟล์) รหัสเหล่านี้ไม่เหมือนกับรหัสเครื่องที่สร้างโดยคอมไพเลอร์ C สำหรับสถาปัตยกรรมดั้งเดิมของเครื่อง อย่างไรก็ตามการใช้งานไพ ธ อนบางตัวนั้นประกอบด้วยคอมไพเลอร์ทันเวลาที่จะรวบรวมไพทอนโค้ดไบต์ลงในโค้ดเนทีฟเครื่อง

(ฉันพูดว่า "สวยมากทุกคน" เพราะฉันไม่รู้คอมไพเลอร์ของเครื่องภาษาไพ ธ อนสำหรับไพ ธ อน แต่ฉันไม่ต้องการอ้างว่าไม่มีใครอยู่เลย)


คอมไพเลอร์ของเครื่องพื้นเมืองสำหรับ Python มีอยู่แล้วตามคำจำกัดความของคุณ บางคนรวบรวมไพ ธ อนเพียงชุดเดียว คนอื่น ๆ ใช้ python ทั้งหมด แต่ใช้ python API เพื่อดำเนินการจริงซึ่งไม่สามารถทำได้ใน C.
Winston Ewert

ฉันคิดว่าคุณกำลังอธิบายว่า Python นั้นเป็นสิ่งที่ฉันจะเรียกว่า 'semi-compiled' หรือสามารถรวบรวมได้จริง โดยการคอมไพล์กึ่งฉันหมายความว่าเนื่องจากมันมักจะรวบรวมไปยังไฟล์ 'ภาษากลาง' ที่ใช้โดย Python Virtual Machine มันมักจะถูกเรียกใช้จากรูปแบบกึ่งคอมไพล์นี้ซึ่งโดยทั่วไปจะทำให้รหัสเร็วกว่า การตีความรันไทม์แบบธรรมดาของโค้ดที่แปล ที่น่าสนใจคือโค้ดที่คอมไพล์กึ่งบางครั้งอาจเร็วกว่าโค้ดที่คอมไพล์แล้ว (เช่น C # โดยทั่วไปจะเร็วกว่า C ++)
Chris Halcrow

5
Cython รวบรวมรหัส Python ถึง C เพื่อให้สามารถรวบรวมเป็นวัตถุที่ใช้ร่วมกัน
greyfade

การแยกแยะรหัสไบต์และรหัสเครื่องในลักษณะนี้ค่อนข้างจะไม่เจาะจง Java ถูกคอมไพล์: คอมไพเลอร์ javac สร้างไฟล์คลาสที่มีคำสั่งระดับต่ำที่อาจถูกดำเนินการทั้งในเครื่องเสมือน (เช่นฮอตสปอต) หรือโดยตรงจากฮาร์ดแวร์ (เช่นบนโปรเซสเซอร์ ARM ด้วยส่วนขยาย Jazelle) เท่าที่ฉันรู้ไม่มีเหตุผลทางเทคนิคสถาปัตยกรรมตัวประมวลผลที่คล้ายกันไม่สามารถออกแบบมาเพื่อรันคำสั่ง python vm โดยตรง
จูลส์

@Jules บังเอิญรหัสJythonถูกคอมไพล์ในไฟล์. class ซึ่งผมเชื่อว่าถูกนำมาใช้ซ้ำจนกว่าคุณจะแก้ไขแหล่งที่มาของ py
JimmyJames

35

Python จะอยู่ภายใต้รหัสไบต์ตีความ รหัสที่มาจะรวบรวมคนแรกที่จะไบต์โค้ด.py .pycรหัสไบต์นี้สามารถตีความได้ (เป็นทางการ CPython) หรือรวบรวม JIT (PyPy) รหัสแหล่ง Python ( .py) สามารถคอมไพล์ไปยังรหัสไบต์ที่แตกต่างกันได้เช่น IronPython (.Net) หรือ Jython (JVM) มีการใช้งานภาษา Python หลายครั้ง หนึ่งอย่างเป็นทางการเป็นรหัสไบต์ตีความหนึ่ง มีโค้ดไบต์ JIT ที่นำไปใช้งานที่คอมไพล์ด้วยเช่นกัน

สำหรับการเปรียบเทียบความเร็วของการใช้งานต่างๆของภาษาที่คุณสามารถลองที่นี่


ขอบคุณสำหรับข้อมูลตามมาตรฐานประสิทธิภาพของหลามก็ลง!
crodjer

1
การเชื่อมโยงผมให้อย่างชัดเจนรัฐเหล่านี้มีมาตรฐานข้อบกพร่องของภาษาการใช้งาน Python ไม่ควรเป็นภาษาที่คุณเลือกถ้าคุณกังวลเกี่ยวกับประสิทธิภาพการทำงานมากเกินไป หากคุณยังต้องการเปรียบเทียบให้เปรียบเทียบภาษาที่คล้ายกัน โค้ดไบต์ตีความอย่างเป็นทางการ CPython เปรียบได้กับหรือเร็วกว่า JIT ที่คอมไพล์ด้วย Ruby
aufather

1
@ jase21 - "แผนการของฉันสำหรับปี 2549 คือการย้ายพอร์ตเทคนิคที่ใช้ใน Psyco ไปยัง PyPy PyPy จะช่วยให้เราสามารถสร้างเครื่องมือพิเศษ JIT ที่ยืดหยุ่นมากขึ้นง่ายต่อการทดสอบและไม่มีค่าใช้จ่ายที่สอดคล้องกับวิวัฒนาการ ภาษา Python " psyco.sourceforge.net/introduction.html
igouy

1
@ jase21 - "ทำให้รหัสหลามทำงานเร็วกว่าชิ้นส่วนตัวนับ C" - เราควรจะเอาคำพูดของคุณไปทำอะไรเหรอ?
igouy

3
ลิงก์ในคำตอบเสียหาย
Basilevs

11

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

เรียบเรียง (ในความหมายกว้าง) เป็นนักแปล มันแปลโปรแกรม A เป็นโปรแกรม B และสำหรับการดำเนินการในอนาคตโดยใช้เครื่อง M

ล่าม (ในความหมายกว้าง) เป็นผู้ปฏิบัติการ เป็นเครื่อง M ที่รันโปรแกรม A แม้ว่าโดยทั่วไปแล้วเราจะแยกออกจากคำจำกัดความของเครื่องทางกายภาพ (หรือเครื่องที่ไม่ใช่เครื่องทางกายภาพที่ทำหน้าที่เหมือนเครื่องทางกายภาพ) แต่จากมุมมองเชิงทฤษฎีแล้วความแตกต่างนั้นค่อนข้างโดยพลการ


re.compileตัวอย่างเช่นใช้ มัน "รวบรวม" regex ไปยังรูปแบบกลางและรูปแบบกลางที่ถูกตีความ / ประเมิน / ดำเนินการ


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

CPython (การใช้ภาษา Python ที่ได้รับความนิยมมากที่สุด) นั้นน่าสนใจสำหรับการใช้งานโค้ด ดังนั้นโดยทั่วไปแล้ว CPython จะอธิบายว่าตีความแล้ว แม้ว่านี่จะเป็นฉลากหลวม


7

รหัสเครื่องเสมือนเป็นรหัสต้นฉบับดั้งเดิมที่มีขนาดกะทัดรัดยิ่งขึ้น (รหัสไบต์) มันยังต้องถูกตีความโดยเครื่องเสมือนเนื่องจากไม่มีรหัสเครื่อง แม้ว่าจะง่ายกว่าและเร็วกว่าในการแยกวิเคราะห์มากกว่าโค้ดต้นฉบับที่เขียนโดยมนุษย์

เครื่องเสมือนบางเครื่องสร้างรหัสเครื่องในขณะแปลรหัสเครื่องเสมือนเป็นครั้งแรก (เพียงในการรวบรวมเวลา - JIT) การเรียกใช้ต่อไปนี้จะใช้รหัสเครื่องนี้โดยตรงซึ่งนำไปสู่การดำเนินการที่รวดเร็วยิ่งขึ้น

เท่าที่ฉันรู้ Ruby> = 1.9 ใช้เครื่องเสมือนเช่น Python เช่นกัน


5

Python รันไทม์รันรหัสวัตถุที่กำหนดเอง (รหัสไบต์) บนเครื่องเสมือน

กระบวนการรวบรวมจะแปลงซอร์สโค้ดเป็นรหัสวัตถุ

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

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