Java“ Virtual Machine” กับ Python“ Interpreter” parlance?


207

ดูเหมือนว่าเป็นการยากที่จะอ่าน Python "virtual machine" ในขณะที่ใน Java "virtual machine" นั้นถูกใช้งานตลอดเวลา

ทั้งตีความรหัสไบต์; ทำไมเรียกหนึ่งเครื่องเสมือนและอื่น ๆ เป็นล่าม

คำตอบ:


137

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

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

คอมไพเลอร์ Java แปลงภาษา Java เป็นสตรีมโค้ดไบต์ไม่แตกต่างจากคอมไพเลอร์ C แปลงโปรแกรมภาษา C เป็นรหัสแอสเซมบลี ล่ามในทางกลับกันไม่ได้แปลงโปรแกรมเป็นรูปแบบกลางใด ๆ ที่กำหนดไว้อย่างดีมันเพียงใช้การกระทำของโปรแกรมเป็นกระบวนการของการตีความแหล่งที่มา

การทดสอบความแตกต่างอีกอย่างหนึ่งระหว่าง VM และล่ามก็คือคุณคิดว่ามันเป็นภาษาที่เป็นอิสระหรือไม่ สิ่งที่เรารู้ในฐานะ Java VM นั้นไม่ใช่เฉพาะ Java จริงๆ คุณสามารถสร้างคอมไพเลอร์จากภาษาอื่นที่ส่งผลให้รหัสไบต์ที่สามารถทำงานบน JVM ในทางกลับกันฉันไม่คิดว่าเราจะคิดถึง "รวบรวม" ภาษาอื่นนอกเหนือจาก Python เป็น Python สำหรับการตีความโดย Python interpreter

เนื่องจากความซับซ้อนของกระบวนการตีความนี้อาจเป็นกระบวนการที่ค่อนข้างช้า .... โดยเฉพาะการแยกวิเคราะห์และระบุโทเค็นภาษา ฯลฯ และทำความเข้าใจบริบทของแหล่งที่มาเพื่อให้สามารถดำเนินการกระบวนการดำเนินการภายในล่าม เพื่อช่วยเร่งการแปลภาษาที่ตีความเช่นนี้เราสามารถกำหนดรูปแบบกลางของซอร์สโค้ดแบบ pre-parsed, pre-tokenized ที่สามารถตีความได้โดยตรง รูปแบบไบนารีประเภทนี้ยังคงถูกตีความ ณ เวลาดำเนินการมันเพิ่งเริ่มจากรูปแบบที่มนุษย์อ่านได้น้อยกว่ามากเพื่อปรับปรุงประสิทธิภาพ อย่างไรก็ตามตรรกะในการดำเนินการกับรูปแบบนั้นไม่ใช่เครื่องเสมือนเพราะรหัสเหล่านั้นยังไม่สามารถแยกออกได้ - บริบทของโทเค็นรอบข้างยังคงสำคัญ


7
ฉันรู้สึกว่าหลามได้สร้างรหัส byte, pyc หรือเป็นสิ่งที่คุณอ้างถึงโดย "ช่วยเร่งการแปลภาษาเช่นนี้เป็นที่ที่เราสามารถกำหนดรูปแบบกลางของการแยกวิเคราะห์ล่วงหน้าซอร์สโค้ดโทเค็นที่มากกว่า ตีความได้อย่างง่ายดายโดยตรง "
James McMahon

32
@InSciTek Jeff: จากคำตอบของคุณยังไม่ชัดเจนว่าคุณรู้หรือไม่ว่า Python ใช้เครื่องเสมือนด้วย
tzot

3
@TZ - การใช้งาน Python ที่ได้รับความนิยมคือคอมไพเลอร์ Python ที่มี VM ด้านหลัง ในโหมดอินเทอร์แอคทีฟมันเป็นไฮบริดเล็กน้อยที่มีทั้งตัวแปลส่วนหน้าและส่วนท้ายคอมไพเลอร์ อย่างไรก็ตามสิ่งเหล่านี้คือทางเลือกในการนำไปปฏิบัติ ฉันพยายามอธิบายความแตกต่างระหว่างแนวคิดของ VM และล่าม
Tall Jeff

8
On the other hand, I don't think we would really think of "compiling" some other language other than Python into Python for interpretation by the Python interpreter.เป็นไปได้ที่จะเขียนภาษาที่สามารถรวบรวมเป็น Python bytecode ได้เช่นเดียวกับ Scala ที่ถูกคอมไพล์เป็น Java bytecode ในโหมดโต้ตอบเชลล์เชิงโต้ตอบของ Python รวบรวมคำสั่งที่คุณพิมพ์ลงใน bytecode แล้วประมวลผล bytecode นั้น คุณสามารถเขียนเชลล์ของคุณเองโดยใช้ eval และ exec และคุณสามารถใช้ฟังก์ชั่นในตัวคอมไพล์ () เพื่อเปลี่ยนสตริงให้เป็น bytecode
Lie Ryan

4
@Lie Ryan ใช่ แต่มันไม่รองรับอย่างเป็นทางการเหมือนกับ JVM ใน Python bytecode เป็นรายละเอียดการใช้งานที่ไม่มีเอกสาร
พลวง

159

ในการโพสต์นี้ "เครื่องเสมือน" หมายถึงการประมวลผลเครื่องเสมือนไม่ใช่ระบบเครื่องเสมือนเช่น Qemu หรือ Virtualbox เครื่องเสมือนกระบวนการเป็นเพียงโปรแกรมที่ให้สภาพแวดล้อมการเขียนโปรแกรมทั่วไป - โปรแกรมที่สามารถตั้งโปรแกรมได้

Java มีล่ามเช่นเดียวกับเครื่องเสมือนและ Python มีเครื่องเสมือนเช่นเดียวกับล่าม เหตุผล "virtual machine" เป็นคำศัพท์ที่พบบ่อยใน Java และ "interpreter" เป็นคำที่พบบ่อยใน Python มีหลายสิ่งที่เกี่ยวข้องกับความแตกต่างที่สำคัญระหว่างสองภาษา: การพิมพ์แบบคงที่ (Java) และการพิมพ์แบบไดนามิก (Python) ในบริบทนี้ "type" หมายถึง ชนิดข้อมูลดั้งเดิม - ชนิดที่แนะนำขนาดการจัดเก็บในหน่วยความจำของข้อมูล เครื่องเสมือน Java นั้นใช้งานง่าย มันต้องการโปรแกรมเมอร์เพื่อระบุชนิดข้อมูลดั้งเดิมของแต่ละตัวแปร สิ่งนี้ให้ข้อมูลที่เพียงพอสำหรับ Java bytecode ไม่เพียง แต่จะถูกตีความและดำเนินการโดยเครื่องเสมือน Java แต่ยังถูกรวบรวมไว้ในคำแนะนำของเครื่อง. เครื่องเสมือน Python มีความซับซ้อนมากขึ้นในแง่ที่ว่าจะใช้ในงานเพิ่มเติมของการหยุดชั่วคราวก่อนที่จะดำเนินการของแต่ละการดำเนินการเพื่อกำหนดชนิดข้อมูลดั้งเดิมสำหรับแต่ละตัวแปรหรือโครงสร้างข้อมูลที่เกี่ยวข้องในการดำเนินการ Python ทำให้โปรแกรมเมอร์ไม่ต้องคิดในแง่ของชนิดข้อมูลดั้งเดิมและช่วยให้การดำเนินการสามารถแสดงในระดับที่สูงขึ้น ราคาของอิสรภาพนี้คือประสิทธิภาพ "Interpreter" เป็นคำที่ต้องการสำหรับ Python เนื่องจากต้องหยุดการตรวจสอบชนิดข้อมูลและเนื่องจากไวยากรณ์ที่กระชับของภาษาที่พิมพ์แบบไดนามิกนั้นค่อนข้างกระชับเหมาะสำหรับอินเตอร์เฟสแบบโต้ตอบ ไม่มีอุปสรรคทางเทคนิคในการสร้างอินเทอร์เฟซ Java แบบโต้ตอบ แต่การพยายามเขียนโค้ดแบบสแตติกใด ๆ แบบโต้ตอบจะน่าเบื่อดังนั้นมันจึงไม่ได้ทำแบบนั้น

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

พกพาตีความภาษาพิมพ์แบบคงที่

สิ่งที่ใกล้เคียงที่สุดต่อไปคือ LLVM แต่ LLVM ทำงานในระดับที่แตกต่างกัน:

ภาษาแอสเซมบลีตีความแบบพกพา

คำว่า "bytecode" ใช้ทั้งใน Java และ Python แต่ bytecode ทั้งหมดไม่ได้ถูกสร้างขึ้นเท่ากัน bytecode เป็นเพียงคำศัพท์ทั่วไปสำหรับภาษากลางที่ใช้โดยคอมไพเลอร์ / ล่าม แม้แต่คอมไพเลอร์ C เช่น gcc ก็ใช้ภาษาระดับกลาง (หรือหลายภาษา)เพื่อทำงานให้เสร็จ Java bytecode มีข้อมูลเกี่ยวกับชนิดข้อมูลดั้งเดิมในขณะที่ Python bytecode ไม่มี ในแง่นี้เครื่องเสมือน Python (และ Bash, Perl, Ruby และอื่น ๆ ) จะช้ากว่าเครื่องเสมือน Java อย่างแท้จริงหรือมากกว่านั้นมันมีงานต้องทำมากกว่า มันมีประโยชน์ที่จะต้องพิจารณาว่าข้อมูลใดที่อยู่ในรูปแบบ bytecode ที่แตกต่างกัน:

  • LLVM:ลงทะเบียน cpu
  • Java:ชนิดข้อมูลดั้งเดิม
  • Python:ประเภทที่ผู้ใช้กำหนด

ในการวาดภาพอะนาล็อกในโลกแห่งความจริง: LLVM ทำงานร่วมกับอะตอมเครื่องเสมือน Java ทำงานกับโมเลกุลและเครื่องเสมือน Python ทำงานกับวัสดุ ในที่สุดทุกอย่างต้องย่อยสลายเป็นอนุภาคย่อย (การทำงานของเครื่องจริง) เครื่องเสมือน Python จึงมีงานที่ซับซ้อนที่สุด

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

เครื่องเสมือนของภาษาแบบไดนามิกเช่น Python ใช้เครื่องโลจิคัลในอุดมคติและไม่จำเป็นต้องสอดคล้องกับฮาร์ดแวร์ทางกายภาพใด ๆ ในทางตรงกันข้าม Java virtual machine นั้นคล้ายกันมากขึ้นในการทำงานกับคอมไพเลอร์ C แบบคลาสสิกยกเว้นว่าแทนที่จะเปล่งคำสั่งเครื่องมันจะเรียกใช้งานรูทีนภายใน ใน Python จำนวนเต็มเป็นออบเจ็กต์ Python ที่มีคุณลักษณะและเมธอดมากมายติดอยู่ ใน Java int มีจำนวนบิตที่กำหนดโดยปกติคือ 32 ไม่ใช่การเปรียบเทียบที่ยุติธรรม Python จำนวนเต็มควรนำมาเปรียบเทียบกับคลาส Java Integer จริงๆ ชนิดข้อมูลดั้งเดิม "int" ของ Java ไม่สามารถเปรียบเทียบกับสิ่งใด ๆ ในภาษา Python ได้เนื่องจากภาษา Python ขาดเลเยอร์ดั้งเดิมเพียงอย่างเดียวและ Python bytecode ก็เช่นกัน

เนื่องจากตัวแปร Java ถูกพิมพ์อย่างชัดเจนเราจึงสามารถคาดหวังได้ว่าบางอย่างเช่นประสิทธิภาพของJythonจะอยู่ใน ballpark เดียวกับ cPython CPythonในทางตรงกันข้าม Java virtual machine ที่ใช้ใน Python นั้นเกือบจะรับประกันว่าจะช้ากว่าโคลน และอย่าคาดหวังว่า Ruby, Perl, และอื่น ๆ พวกเขาไม่ได้ออกแบบมาเพื่อทำเช่นนั้น พวกเขาถูกออกแบบมาสำหรับ "การเขียนสคริปต์" ซึ่งเป็นสิ่งที่เรียกว่าการเขียนโปรแกรมในภาษาแบบไดนามิก

ในที่สุดการดำเนินการทุกอย่างที่เกิดขึ้นในเครื่องเสมือนจะต้องใช้ฮาร์ดแวร์จริง เครื่องเสมือนมีรูทีนที่รวบรวมไว้ล่วงหน้าซึ่งโดยทั่วไปเพียงพอที่จะเรียกใช้งานการดำเนินการทางตรรกะใด ๆ เครื่องเสมือนอาจไม่ได้เปล่งคำสั่งเครื่องใหม่ แต่แน่นอนว่ามันกำลังประมวลผลกิจวัตรของตัวเองซ้ำแล้วซ้ำอีกในลำดับที่ซับซ้อนโดยไม่ตั้งใจ เครื่องเสมือน Java, เครื่องเสมือน Python และเครื่องเสมือนทั่วไปอื่น ๆ ทั้งหมดนั้นมีความเท่าเทียมกันในแง่ที่ว่าพวกเขาสามารถเกลี้ยกล่อมให้ดำเนินการกับตรรกะใด ๆ ที่คุณสามารถฝันได้ แต่แตกต่างกันในแง่ของงานที่พวกเขาทำ รับและสิ่งที่พวกเขาปล่อยให้โปรแกรมเมอร์

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

คุณธรรมของเรื่องราวคือข้อมูลประเภทข้อมูลดั้งเดิมนั้นมีประโยชน์ต่อคอมไพเลอร์ / เครื่องเสมือนจริง ๆ

ท้ายที่สุดสิ่งที่ควรพิจารณา: โปรแกรม Python ที่ดำเนินการโดย Python interpreter / virtual machine ที่ใช้ใน Java ที่รันบน Java interpreter / virtual machine ที่ใช้ใน LLVM ที่รันใน qemu virtual machine ที่ทำงานบน iPhone

ความคิดเห็น


1
trying to write any statically-typed code interactively would be tedious. ถ้าคุณรู้ว่า OCaml และ Haskell คุณจะเห็นว่าไม่เป็นความจริงเนื่องจากพวกเขามีมากภาษารัดกุมแบบคงที่พิมพ์
Matthias Braun

@MatthiasBraun ฉันสามารถยอมรับได้ว่าภาษาที่ใช้งานได้เหล่านั้นสร้างรหัสที่กระชับ แต่นั่นไม่ได้หมายความว่าพวกเขาจะเหมาะสำหรับโหมดการโต้ตอบ หาก OCaml และ Haskell พิมพ์แบบไดนามิกเช่น lisp พวกเขาจะทำงานได้ดีขึ้นสำหรับโหมดโต้ตอบที่ฉันสมมติ
ระเบิด

58

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

ใน Java คุณจะต้องคอมไพล์โค้ดไบต์อย่างชัดเจนจากนั้นรันโค้ดไบต์เท่านั้นไม่ใช่ซอร์สโค้ดบน VM

แม้ว่า Python จะใช้เครื่องเสมือนภายใต้ฝาปิด แต่จากมุมมองของผู้ใช้ผู้ใช้สามารถเพิกเฉยต่อรายละเอียดนี้ได้เกือบตลอดเวลา


1
ฉันเห็นด้วย. ความแตกต่างของคำศัพท์นี้มาจากประสบการณ์ของผู้ใช้ปลายทาง (ผู้พัฒนาคือ) จริงๆ มันไม่มีอะไรเกี่ยวข้องกับความแตกต่างทางเทคนิคที่แท้จริงเนื่องจากสายเทคนิคเบลออย่างไม่น่าเชื่อจนแทบจะไม่มีเลย
Cody Brocious

1
+1: และ - สำคัญกว่า - ประเด็นคืออะไร คุณเขียนโปรแกรมอะไรไม่ได้เนื่องจากความแตกต่างนี้ การย้อนกลับสแต็คใดทำให้คุณสับสน? ห้องสมุดใดทำงานไม่ถูกต้อง
S.Lott

@ S.Lott เพราะมันดีเสมอที่จะได้รับข้อโต้แย้งกับเพื่อนร่วมงาน ;)
Qix - MONICA ถูกยกเลิก

16

ล่ามแปลซอร์สโค้ดเป็นการนำเสนอระดับกลางที่มีประสิทธิภาพ (รหัส) และดำเนินการสิ่งนี้ทันที

Virtual Machineเรียกใช้งานโค้ดที่รวบรวมไว้ล่วงหน้าที่สร้างโดยคอมไพเลอร์ซึ่งเป็นส่วนหนึ่งของระบบล่ามอย่างชัดเจน

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

ในกรณีของงูหลามถ้าเรารักษาpycไฟล์ดังที่ได้กล่าวไว้ในความคิดเห็นของโพสต์นี้กลไกจะกลายเป็นเหมือน VM และ bytecode นี้ทำงานได้เร็วขึ้น - มันจะถูกตีความ แต่จากรูปแบบที่เป็นมิตรกับคอมพิวเตอร์มาก . ถ้าเราดูทั้งหมดนี้ PVM เป็นขั้นตอนสุดท้ายของ Python Interpreter

บรรทัดล่างคือเมื่ออ้างถึง Python Interpreter นั่นหมายความว่าเราอ้างถึงโดยรวมและเมื่อเราพูดว่า PVM นั่นหมายถึงเรากำลังพูดถึงส่วนหนึ่งของ Python Interpreter ซึ่งเป็นสภาวะแวดล้อมรันไทม์ คล้ายกับที่ของ Java เราอ้างอิงส่วนต่าง differentyl, JRE, JVM, JDK ฯลฯ

สำหรับข้อมูลเพิ่มเติมเข้าวิกิพีเดีย: ล่ามและเครื่องเสมือน แต่อีกคนหนึ่งที่นี่ ที่นี่คุณสามารถค้นหาเปรียบเทียบเครื่องเสมือนแอพลิเคชัน ช่วยในการทำความเข้าใจความแตกต่างระหว่าง Compilers, Interpreters และ VMs


12

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

Python interpreter ยังคงทำงานในลักษณะเดียวกับเชลล์สคริปต์ในแง่ที่ว่ามันสามารถดำเนินการได้โดยไม่มีขั้นตอนการคอมไพล์แยกต่างหาก นอกเหนือจากนั้นความแตกต่างระหว่าง Python interpreter (หรือ Perl หรือ Ruby) และ virtual machine ของ Java นั้นส่วนใหญ่จะมีรายละเอียดการใช้งาน (หนึ่งอาจยืนยันว่า Java เป็น sandboxed อย่างเต็มที่มากกว่า Python แต่ในที่สุดทั้งสองก็ให้การเข้าถึงสถาปัตยกรรมพื้นฐานผ่านอินเตอร์เฟซ C พื้นเมือง)


1
มีจาวาเชลล์ที่สามารถรันโค้ดจาวาได้โดยไม่ต้องมีขั้นตอนการคอมไพล์แยกต่างหาก
Lie Ryan

1
ขอชื่อ: D
Maciej Nowicki

11

เพื่อให้คำตอบอย่างลึกซึ้งสำหรับคำถาม " ทำไมต้องใช้ Java Virtual Machine แต่เป็น Python interpreter? " ให้เราลองย้อนกลับไปที่ทฤษฎีการรวบรวมซึ่งเป็นจุดเริ่มต้นของการอภิปราย

กระบวนการทั่วไปของการคอมไพล์โปรแกรมรวมถึงขั้นตอนถัดไป:

  1. วิเคราะห์คำศัพท์ แยกข้อความของโปรแกรมออกเป็น "คำ" ที่มีความหมายเรียกว่าโทเค็น (เป็นส่วนหนึ่งของกระบวนการความคิดเห็นการเว้นวรรคบรรทัดใหม่ ฯลฯ ทั้งหมดจะถูกลบออกเนื่องจากไม่ได้ส่งผลกระทบต่อพฤติกรรมของโปรแกรม) ผลลัพธ์คือโทเค็นสตรีมที่สั่งซื้อแล้ว
  2. การวิเคราะห์ไวยากรณ์ สร้างต้นไม้ที่เรียกว่าบทคัดย่อไวยากรณ์ (AST)จากกระแสของโทเค็น AST สร้างความสัมพันธ์ระหว่างโทเค็นและกำหนดลำดับของการประเมินผลของโปรแกรม
  3. การวิเคราะห์ความหมาย ตรวจสอบความถูกต้องทางอรรถศาสตร์ของ AST โดยใช้ข้อมูลเกี่ยวกับประเภทและชุดของกฎความหมายของภาษาการเขียนโปรแกรม (ตัวอย่างเช่นa = b + cเป็นคำสั่งที่ถูกต้องจากมุมมองไวยากรณ์ แต่ไม่ถูกต้องสมบูรณ์จากมุมมองเชิงความหมายหากaถูกประกาศเป็นวัตถุคงที่)
  4. รหัสรุ่นระดับกลาง จัดลำดับ AST เป็นกระแสการสั่งซื้อแบบเชิงเส้นของการดำเนินการ "ดั้งเดิม" โดยอิสระของเครื่องจักร ในความเป็นจริงแล้วตัวสร้างโค้ดจะสำรวจ AST และบันทึกลำดับขั้นตอนการประเมินผล ด้วยเหตุนี้จากการแสดงแบบทรีของโปรแกรมเราจึงได้การแสดงแบบรายการที่เรียบง่ายมากขึ้นซึ่งลำดับการประเมินโปรแกรมจะถูกเก็บไว้
  5. รุ่นรหัสเครื่อง โปรแกรมในรูปแบบของ "ไบต์" ดั้งเดิมของเครื่องจะถูกแปลเป็นรหัสเครื่องของสถาปัตยกรรมตัวประมวลผลเฉพาะ

ตกลง. ตอนนี้ให้กำหนดเงื่อนไข

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

หากเราเปลี่ยนขั้นตอนการดำเนินการตาม AST ในการสร้างขั้นตอนไบนารี bytecode แบบไม่ขึ้นอยู่กับเครื่องจักรในล่ามเราจะแบ่งกระบวนการทั้งหมดของการดำเนินการโปรแกรมออกเป็นสองขั้นตอนแยกจากกัน: การรวบรวมและการดำเนินการ ในกรณีนั้นสิ่งที่เคยเป็นล่ามก่อนหน้านี้จะกลายเป็นคอมไพเลอร์ bytecode ซึ่งจะแปลงโปรแกรมจากรูปแบบของข้อความเป็นรูปแบบไบนารีบางส่วน จากนั้นโปรแกรมจะเผยแพร่ในรูปแบบไบนารีนั้น แต่ไม่ได้อยู่ในรูปของรหัสต้นฉบับ บนเครื่องของผู้ใช้ไบต์นั้นจะถูกป้อนเข้าสู่เอนทิตีใหม่ - เครื่องเสมือนซึ่งในความเป็นจริงตีความว่า bytecode ด้วยเหตุนี้เครื่องเสมือนจึงถูกเรียกว่าbytecode interpreter ล่าม แต่ใส่ความสนใจของคุณที่นี่! ล่ามคลาสสิคคือtext interpreterแต่เครื่องเสมือนเป็นแปลไบนารี ! นี่เป็นวิธีการที่ดำเนินการโดย Java และ C #

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

ตอนนี้ให้กลับไปที่คำถามเดิมและพิจารณา Java vs Python

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

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

เนื่องจากนี้ในอดีตJavaนักพัฒนามีแนวโน้มที่จะพูดคุยเกี่ยวกับโปรแกรม Java Virtual Machine (เพราะตอนแรกJavaได้มาเป็นแพคเกจของJavaคอมไพเลอร์ bytecode และbytecode ล่าม - JVM ) และงูหลามนักพัฒนามีแนวโน้มที่จะพูดคุยเกี่ยวกับงูหลามล่าม (เพราะตอนแรกงูใหญ่มี ไม่ใช่เครื่องเสมือนและเป็นล่ามข้อความคลาสสิคที่รันข้อความโปรแกรมโดยตรงโดยไม่มีการคอมไพล์หรือแปลงในรูปแบบของรหัสไบนารี่ใด ๆ )

ปัจจุบันไพ ธ อนยังมีเครื่องเสมือนภายใต้ประทุนและสามารถรวบรวมและตีความ Python bytecode และความจริงนั้นทำให้การลงทุนเพิ่มเติมในความสับสน " ทำไม Java Virtual Machine แต่เป็น Python interpreter?และโปรแกรมนั้นจะแสดงให้เห็นถึงพฤติกรรมที่เหมือนกันและสร้างผลลัพธ์เดียวกันจากอินพุตที่เท่ากัน ความแตกต่างที่สังเกตได้เท่านั้นคือความเร็วของการเรียกใช้โปรแกรมและปริมาณหน่วยความจำที่ล่ามใช้ ดังนั้นเครื่องเสมือนใน Python จึงไม่ใช่ส่วนที่หลีกเลี่ยงไม่ได้ในการออกแบบภาษา แต่เป็นเพียงส่วนเสริมเสริมของ Python interpreter

Java สามารถพิจารณาในลักษณะที่คล้ายกัน Java ภายใต้ประทุนมีคอมไพเลอร์ JIT และสามารถรวบรวมวิธีการของคลาส Java เป็นรหัสเครื่องของแพลตฟอร์มเป้าหมายแล้วดำเนินการโดยตรง แต่! Java ยังคงใช้การตีความ bytecode เป็นวิธีหลักของการเรียกใช้โปรแกรม Java เช่นเดียวกับการใช้งาน Python ซึ่งใช้ประโยชน์จากเครื่องเสมือนภายใต้ประทุนเป็นเทคนิคการปรับให้เหมาะสมที่สุดเครื่องเสมือน Java ใช้ Just-In-Time compilers เพื่อการปรับให้เหมาะสมโดยเฉพาะ ในทำนองเดียวกันเพียงเพราะการดำเนินการโดยตรงของรหัสเครื่องอย่างน้อยสิบครั้งเร็วกว่าการตีความของ Java bytecode และเช่นเดียวกับในกรณีของ Python การมี JIT compiler ภายใต้ประทุนของ JVM นั้นโปร่งใสสำหรับนักออกแบบภาษา Java และนักพัฒนาโปรแกรม Java อย่างแน่นอน ภาษาโปรแกรม Java เดียวกันสามารถนำไปใช้โดย JVM โดยมีและไม่มีคอมไพเลอร์ JIT และในทำนองเดียวกันโปรแกรมเดียวกันสามารถดำเนินการใน JVM โดยมีและไม่มี JIT อยู่ภายในและโปรแกรมเดียวกันจะแสดงให้เห็นถึงพฤติกรรมเดียวกันและสร้างผลลัพธ์เดียวกันจากอินพุตที่เท่ากันบน JVM ทั้งที่มีและไม่มี JIT และเช่นเดียวกับในกรณีของ Python ความแตกต่างที่สังเกตได้เพียงอย่างเดียวคือความเร็วในการประมวลผลและปริมาณหน่วยความจำที่ใช้โดย JVM และในที่สุดเช่นในกรณีของ Python JIT ใน Java ก็ไม่ได้เป็นส่วนหนึ่งของการออกแบบภาษาอย่างหลีกเลี่ยงไม่ได้ แต่เป็นเพียงส่วนเสริมของการใช้งาน JVM ที่สำคัญ และโปรแกรมเดียวกันจะแสดงให้เห็นถึงพฤติกรรมที่เหมือนกันและสร้างผลลัพธ์เดียวกันจากอินพุตที่เท่ากันบน JVM ทั้งสอง (โดยมีและไม่มี JIT) และเช่นเดียวกับในกรณีของ Python ความแตกต่างที่สังเกตได้เพียงอย่างเดียวคือความเร็วในการประมวลผลและปริมาณหน่วยความจำที่ใช้โดย JVM และในที่สุดเช่นในกรณีของ Python JIT ใน Java ก็ไม่ได้เป็นส่วนหนึ่งของการออกแบบภาษาอย่างหลีกเลี่ยงไม่ได้ แต่เป็นเพียงส่วนเสริมของการใช้งาน JVM ที่สำคัญ และโปรแกรมเดียวกันจะแสดงให้เห็นถึงพฤติกรรมที่เหมือนกันและสร้างผลลัพธ์เดียวกันจากอินพุตที่เท่ากันบน JVM ทั้งสอง (โดยมีและไม่มี JIT) และเช่นเดียวกับในกรณีของ Python ความแตกต่างที่สังเกตได้เพียงอย่างเดียวคือความเร็วในการประมวลผลและปริมาณหน่วยความจำที่ใช้โดย JVM และในที่สุดเช่นในกรณีของ Python JIT ใน Java ก็ไม่ได้เป็นส่วนหนึ่งของการออกแบบภาษาอย่างหลีกเลี่ยงไม่ได้ แต่เป็นเพียงส่วนเสริมของการใช้งาน JVM ที่สำคัญ

จากมุมมองของการออกแบบและการใช้งานเครื่องเสมือนของ Java และ Python พวกเขาแตกต่างกันอย่างมีนัยสำคัญในขณะที่ (ความสนใจ!) ทั้งสองยังคงอยู่เครื่องเสมือน JVM เป็นตัวอย่างของเครื่องเสมือนระดับต่ำที่มีการใช้งานพื้นฐานอย่างง่ายและค่าใช้จ่ายในการส่งคำสั่งสูง หลามในตอนนั้นเป็นเครื่องเสมือนระดับสูงซึ่งคำสั่งแสดงให้เห็นถึงพฤติกรรมที่ซับซ้อนและค่าใช้จ่ายในการจัดส่งคำสั่งไม่สำคัญนัก Java ทำงานด้วยระดับนามธรรมที่ต่ำมาก JVM ทำงานกับชุดประเภทดั้งเดิมขนาดเล็กที่กำหนดไว้อย่างดีและมีการติดต่อที่แน่นมาก ในทางกลับกันเครื่องเสมือน Python ทำงานที่ระดับนามธรรมสูงมันทำงานกับชนิดข้อมูลที่ซับซ้อน (วัตถุ) และสนับสนุน ad-hoc polymorphism ในขณะที่คำสั่ง bytecode เปิดเผยพฤติกรรมที่ซับซ้อนซึ่งสามารถแสดงด้วยชุดคำสั่งรหัสเครื่องหลายแบบ ตัวอย่างเช่น Python สนับสนุนคณิตศาสตร์ในขอบเขตที่ไม่ จำกัด ดังนั้น Python VM ถูกบังคับให้ใช้ประโยชน์จาก arithmetics ยาวสำหรับจำนวนเต็มขนาดใหญ่ที่อาจเป็นผลของการดำเนินการสามารถล้นคำเครื่อง ดังนั้นคำสั่ง bytecode หนึ่งคำสำหรับ arithmetics ใน Python สามารถเปิดเผยในการเรียกใช้ฟังก์ชั่นภายใน Python VM ในขณะที่การดำเนินการทางคณิตศาสตร์ JVM จะเปิดเผยในการดำเนินการอย่างง่ายที่แสดงโดยคำสั่งเครื่องพื้นเมืองหนึ่งหรือสองสามตัว ดังนั้น Python VM ถูกบังคับให้ใช้ประโยชน์จาก arithmetics ยาวสำหรับจำนวนเต็มขนาดใหญ่ที่อาจเป็นผลของการดำเนินการสามารถล้นคำเครื่อง ดังนั้นคำสั่ง bytecode หนึ่งคำสำหรับ arithmetics ใน Python สามารถเปิดเผยในการเรียกใช้ฟังก์ชั่นภายใน Python VM ในขณะที่การดำเนินการทางคณิตศาสตร์ JVM จะเปิดเผยในการดำเนินการอย่างง่ายที่แสดงโดยคำสั่งเครื่องพื้นเมืองหนึ่งหรือสองสามตัว ดังนั้น Python VM ถูกบังคับให้ใช้ประโยชน์จาก arithmetics ยาวสำหรับจำนวนเต็มขนาดใหญ่ที่อาจเป็นผลของการดำเนินการสามารถล้นคำเครื่อง ดังนั้นคำสั่ง bytecode หนึ่งคำสำหรับ arithmetics ใน Python สามารถเปิดเผยในการเรียกใช้ฟังก์ชั่นภายใน Python VM ในขณะที่การดำเนินการทางคณิตศาสตร์ JVM จะเปิดเผยในการดำเนินการอย่างง่ายที่แสดงโดยคำสั่งเครื่องพื้นเมืองหนึ่งหรือสองสามตัว

เป็นผลให้เราสามารถสรุปข้อสรุปต่อไป Java Virtual Machine แต่ตัวแปล Python เป็นเพราะ:

  1. เงื่อนไขของเครื่องเสมือนถือว่าการตีความแบบไบนารี bytecode ในขณะที่คำล่ามถือว่าการตีความข้อความของโปรแกรม
  2. ในอดีต Java ได้รับการออกแบบและนำมาใช้สำหรับการตีความ bytecode ไบนารีและ Python ได้รับการออกแบบและนำมาใช้สำหรับการตีความข้อความของโปรแกรม ดังนั้นคำว่า "Java Virtual Machine" จึงเป็นประวัติศาสตร์และเป็นที่ยอมรับในชุมชน Java และในทำนองเดียวกันคำว่า "Python Interpreter" นั้นมีประวัติมายาวนานและได้รับการยอมรับอย่างดีในชุมชน Python ผู้คนมีแนวโน้มที่จะยืดประเพณีและใช้คำเดิมที่เคยใช้มานาน
  3. ในที่สุดปัจจุบันสำหรับ Java การตีความ bytecode แบบไบนารีเป็นวิธีหลักของการดำเนินการโปรแกรมในขณะที่การรวบรวม JIT เป็นเพียงการเพิ่มประสิทธิภาพที่เป็นทางเลือกและโปร่งใส และสำหรับ Python ปัจจุบันการตีความข้อความของโปรแกรมเป็นวิธีหลักของการดำเนินการโปรแกรม Python ในขณะที่การคอมไพล์ลงใน Python VM bytecode เป็นเพียงการเพิ่มประสิทธิภาพที่เป็นทางเลือกและโปร่งใส

ดังนั้นทั้ง Java และ Python มีเครื่องเสมือนเป็นตัวแปลไบนารี bytecode ซึ่งสามารถนำไปสู่ความสับสนเช่น " Why Java Virtual Machine แต่เป็น Python interpreter? " จุดสำคัญที่นี่คือสำหรับ Python เครื่องเสมือนไม่ใช่วิธีหลักหรือจำเป็นสำหรับการดำเนินการของโปรแกรม มันเป็นเพียงส่วนเสริมเสริมของล่ามข้อความคลาสสิก ในอีกทางหนึ่งเครื่องเสมือนเป็นแกนหลักและเป็นส่วนที่หลีกเลี่ยงไม่ได้ของระบบนิเวศในการทำงานของโปรแกรม Java ตัวเลือกการพิมพ์แบบคงที่หรือแบบไดนามิกสำหรับการออกแบบภาษาการเขียนโปรแกรมส่งผลกระทบส่วนใหญ่เป็นระดับนามธรรมของเครื่องเสมือนเท่านั้น แต่ไม่ได้กำหนดว่าต้องใช้เครื่องเสมือนหรือไม่ ภาษาที่ใช้ระบบการพิมพ์ทั้งสองสามารถออกแบบให้คอมไพล์ตีความหรือดำเนินการภายในสภาพแวดล้อมของเครื่องเสมือนทั้งนี้ขึ้นอยู่กับรูปแบบการดำเนินการที่ต้องการ


2
ควรเลือกให้เป็นคำตอบอย่างเป็นทางการของ IMHO
Ravikanth Andhavarapu

คำตอบอย่างเป็นทางการควรโดย YES เนื่องจาก "ทั้ง Java และ Python มีเครื่องเสมือนเป็นตัวแปลไบนารี bytecode" ระยะเวลา
stuartw

10

ไม่มีความแตกต่างที่แท้จริงระหว่างพวกเขาผู้คนเพียงทำตามแบบแผนที่ผู้สร้างเลือกไว้


3
ฉันจะโยนกระดูกให้คุณที่นี่เพราะฉันคิดว่านี่อาจเป็นคำตอบที่แท้จริงและคุณได้รับการโหวตเพราะขาดบิต
vikingben

3

อย่าลืมว่า Python มีคอมไพเลอร์ JIT สำหรับ x86 ทำให้เกิดความสับสนมากขึ้น (ดู psyco)

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


1
มันผิด ครั้งแรกไม่มีสิ่งเช่น "ภาษาตีความ" การดำเนินการใช้คอมไพเลอร์หรือล่ามไม่ใช่ลักษณะของภาษา แต่เป็นการนำไปใช้ ข้อที่สองจากการติดตั้ง Ruby ที่ 13 หรือมากกว่านั้นคือ 1 เป็นล่ามซึ่งคนอื่น ๆ ทั้งหมดมีคอมไพเลอร์
Jörg W Mittag

2
ประการที่สามทับทิมไม่ช้า ไม่มีภาษาที่ช้าเพราะความเร็วไม่ใช่ลักษณะของภาษา แต่เป็นการใช้ภาษา จากการใช้งาน Ruby ตั้งแต่ 13 ปีขึ้นไปบางอย่างช้ากว่าการปรับใช้ 7 Python บางตัวเร็วกว่า
Jörg W Mittag

ฉันคิดว่าเขากำลังเปรียบเทียบการใช้งานมาตรฐานที่นี่Jörg CPython และ Ruby (ฉันคิดว่าการนำไปปฏิบัติอย่างเป็นทางการนั้นมีชื่อว่า Ruby)
James McMahon

ในขณะที่อารากองเนียนอาจหมายถึงการใช้งาน "มาตรฐาน" เขาควรจะพูดอย่างนั้น ฉันเป็น Pythonista แต่ฉันไม่ชอบคำแถลงใด ๆของแบบฟอร์ม "Language X ช้า" เนื่องจากฉันเห็นด้วยกับJörgเกี่ยวกับการใช้งาน
tzot

1
นี่คือเหตุผลที่ฉันพูดว่า "เคยเป็น (คืออะไร)" และโดยเฉพาะอย่างยิ่งคำว่า "ช้าลง" ฉันไม่รู้ว่าทับทิมอยู่ในตัวของมันเองช้า
Arafangion

2

Python สามารถตีความรหัสได้โดยไม่ต้องคอมไพล์โค้ดดังกล่าวเป็น bytecode Java ไม่สามารถ

Python เป็นภาษาที่ถูกตีความเมื่อเทียบกับภาษาที่รวบรวมแม้ว่าความแตกต่างสามารถเลือนลางเนื่องจากการมีอยู่ของคอมไพเลอร์ bytecode ซึ่งหมายความว่าไฟล์ต้นฉบับสามารถรันได้โดยตรงโดยไม่ต้องสร้างไฟล์ที่รันได้อย่างชัดเจน

(จากเอกสาร)

ใน java ทุกไฟล์จะต้องรวบรวมเป็น.classไฟล์ซึ่งจะทำงานบน JVM ในทางกลับกันไพ ธ อนนำเข้าโดยสคริปต์หลักของคุณเพื่อช่วยเร่งการใช้ไฟล์เหล่านั้นในภายหลัง

อย่างไรก็ตามในกรณีทั่วไปรหัสไพ ธ อนส่วนใหญ่ (อย่างน้อย CPython) ทำงานในเครื่องจำลองแบบสแต็กซึ่งมีคำแนะนำที่เหมือนกันเกือบทั้งหมดกับ JVM ดังนั้นจึงไม่มีความแตกต่างกัน

อย่างไรก็ตามเหตุผลที่แท้จริงของความแตกต่างคือเนื่องจากจาวาได้สร้างตราสินค้าของตัวเองว่าเป็น "bytecode แบบพกพาที่ปฏิบัติการได้" และไพ ธ อนทำเครื่องหมายว่าเป็นภาษาไดนามิกแปลภาษาด้วย REPL ชื่อติด!


0

ก่อนอื่นคุณควรเข้าใจว่าการเขียนโปรแกรมหรือวิทยาศาสตร์คอมพิวเตอร์โดยทั่วไปไม่ใช่คณิตศาสตร์และเราไม่มีคำจำกัดความที่เข้มงวดสำหรับคำศัพท์ส่วนใหญ่ที่เราใช้บ่อย

ตอนนี้คำถามของคุณ:

ล่ามคืออะไร (ในสาขาวิทยาศาสตร์คอมพิวเตอร์)

มันแปลซอร์สโค้ดด้วยหน่วยปฏิบัติการที่เล็กที่สุดจากนั้นเรียกใช้งานหน่วยนั้น

เครื่องเสมือนคืออะไร

ในกรณีของ JVM เครื่องเสมือนเป็นซอฟต์แวร์ที่มีตัวแปล, ตัวโหลดคลาส, ตัวรวบรวมขยะ, ตัวกำหนดเวลาเธรด, ตัวแปล JIT และสิ่งอื่น ๆ อีกมากมาย

ในขณะที่คุณเห็นล่ามเป็นส่วนหนึ่งหรือ JVM และ JVM ทั้งหมดไม่สามารถเรียกว่าล่ามเพราะมันมีส่วนประกอบอื่น ๆ

เหตุใดจึงใช้คำว่า "ล่าม" เมื่อพูดถึงงูหลาม

ด้วย java ส่วนการรวบรวมนั้นชัดเจน งูหลามในทางกลับกันไม่ชัดเจนว่าเป็นจาวาเกี่ยวกับการรวบรวมและการตีความของมันจากการตีความมุมมองของผู้ใช้เป็นกลไกเดียวที่ใช้ในการรันโปรแกรมหลาม


0

ไม่พวกเขาทั้งสองไม่ตีความรหัสไบต์

Python ตีความเฉพาะ bytecode หากคุณใช้งานกับ pypy มิฉะนั้นจะรวบรวมเป็น C และตีความในระดับนั้น

Java คอมไพล์ไปยัง bytecode


คุณสามารถให้ทรัพยากรใด ๆ กับคำตอบของคุณ?
Isuru Dilshan

และนี่คือบน Java: en.wikipedia.org/wiki/Java_virtual_machine
Michael Tamillow

นี่คือสิ่งที่ผิดปกติกับ Stack Overflow บางคนมีอาการหน้ามืดเพราะถูกเรียกออกมาและแสดงออกด้วยการลงคะแนน
Michael Tamillow

0

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

ขณะนี้ทั้ง Java และ Python มีเครื่องเสมือนและ bytecode แม้ว่าหนึ่งดำเนินการโดยขนาดค่าคอนกรีต (เช่นจำนวนเต็ม 32 บิต) ในขณะที่อื่น ๆ มีการกำหนดขนาดสำหรับการโทรแต่ละครั้งซึ่งในความคิดของฉันไม่ได้กำหนดชายแดนระหว่างเงื่อนไข

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

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

ไม่มีความแตกต่างระหว่างนักฆ่ามีเพียงความแตกต่างของการใช้งานบางอย่างและการปรับให้เหมาะสมซึ่งไม่เกี่ยวข้องกับผู้ใช้อาจจะถึงจุดที่เธอเริ่มสังเกตเห็นความล่าช้าของประสิทธิภาพ แต่อีกครั้งเป็นการใช้งานและไม่ใช่ปัญหาสถาปัตยกรรม


0

สำหรับโพสต์ที่พูดถึงว่าหลามไม่จำเป็นต้องสร้างรหัสไบต์ฉันไม่แน่ใจว่ามันเป็นเรื่องจริง ดูเหมือนว่า callables ทั้งหมดใน Python จะต้องมี.__code__.co_codeคุณลักษณะที่มีรหัสไบต์ ฉันไม่เห็นเหตุผลที่มีความหมายในการเรียก python "ไม่ได้รวบรวม" เพียงเพราะสิ่งที่รวบรวมอาจไม่ถูกบันทึก; และบ่อยครั้งที่ไม่ได้รับการบันทึกโดยการออกแบบใน Python ตัวอย่างเช่น comprehension compileension bytecode ใหม่สำหรับ input มันนี่คือเหตุผลที่ขอบเขตของตัวแปร comprehension ไม่สอดคล้องกันcompile(mode='exec, ...)และระหว่างการคอมไพล์compile(mode='single', ...)เช่นระหว่างการเรียกใช้สคริปต์ python และการใช้ pdb

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