Java “Sanal Makine” mi, Python “Tercüman” mı?


207

Java "sanal makine" her zaman kullanılırken bir Python "sanal makine" okumak nadir gibi görünüyor.

Her ikisi de bayt kodlarını yorumlar; Neden birine sanal makine, diğerine tercüman diyelim?

Yanıtlar:


137

Sanal makine, belirli bir dilden bağımsız olarak desteklenen belirli bir dizi atomik iyi tanımlanmış yönergeye sahip sanal bir bilgi işlem ortamıdır ve genellikle kendi başına bir sanal alan olarak düşünülür. VM, belirli bir CPU'nun talimat setine benzer ve bu talimatların (veya bayt kodlarının) sonrakinden bağımsız olan çok temel yapı taşlarıyla daha temel bir seviyede çalışma eğilimindedir. Bir komut, yalnızca sanal makinenin geçerli durumuna bağlı olarak deterministik olarak yürütülür ve o sırada talimat akışında başka bir yerde bulunan bilgilere bağlı değildir.

Öte yandan, bir tercüman, belirli bir dile ait belirli bir sözdiziminin ve çevreleyen belirteçlerin bağlamında çözülmesi gereken belirli bir dilbilgisinin bir akışını ayrıştırmak için uyarlanmış olması nedeniyle daha karmaşıktır. Her bayta ve hatta her satıra ayrı olarak bakamazsınız ve bundan sonra ne yapacağınızı tam olarak bilemezsiniz. Dildeki belirteçler, bir VM'nin yönergelerine (bayt kodları) göre ayrı ayrı alınamaz.

Bir Java derleyicisi, Java dilini C derleyicisinden farklı olmayan bir bayt kodu akışına dönüştürür. C Dili programlarını derleme koduna dönüştürür. Öte yandan bir tercüman, programı gerçekten iyi tanımlanmış herhangi bir ara formata dönüştürmez, sadece program eylemlerini, kaynağı yorumlama süreci olarak alır.

Bir VM ve bir tercüman arasındaki farkın bir başka testi, bunun dilden bağımsız olduğunu düşünüp düşünmediğinizdir. Java VM olarak bildiğimiz gerçekte Java'ya özgü değildir. JVM'de çalıştırılabilecek bayt kodları ile sonuçlanan diğer dillerden bir derleyici yapabilirsiniz. Öte yandan, Python'dan başka bir dili Python yorumlayıcısı tarafından yorumlanması için Python'a "derlemeyi" düşüneceğimizi sanmıyorum.

Yorumlama sürecinin karmaşıklığı nedeniyle, bu nispeten yavaş bir süreç olabilir .... özellikle dil belirteçlerini ayrıştırmak ve tanımlamak ve yorumlayıcı içinde yürütme sürecini üstlenecek kaynağın bağlamını anlamak. Bu tür yorumlanmış dillerin hızlanmasına yardımcı olmak için, önceden doğrudan yorumlanmış, önceden ayrıştırılmış, önceden belirtilmiş kaynak kodunun ara formlarını tanımlayabileceğimiz yer burasıdır. Bu tür ikili form, yürütme zamanında hala yorumlanır, performansı iyileştirmek için daha az insan tarafından okunabilir formdan başlar. Bununla birlikte, bu formu yürüten mantık sanal bir makine değildir, çünkü bu kodlar hala tek başına alınamaz - çevreleyen belirteçlerin bağlamı hala önemlidir, şimdi daha farklı bir bilgisayar etkin formundadırlar.


7
Python'un bayt kodu, pyc oluşturduğu izlenimindeydim ya da bu tür yorumlanmış dilleri hızlandırmaya yardımcı olan "atıfta bulunduğunuz şey" kolayca doğrudan yorumlanır. "
James McMahon

32
@InSciTek Jeff: Cevabınızdan Python'un da sanal bir makine kullanıp kullanmadığını bilmiyorsunuz.
tzot

3
@TZ - Popüler Python uygulaması, arka tarafı VM'ye sahip bir Python derleyicisidir. Etkileşimli modda, hem tercüman ön ucu hem de derleyici arka ucu ile biraz melezdir. Ancak bunlar uygulama seçimleridir. VM kavramı ve Tercüman arasındaki farkı anlatmaya çalıştım
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.Tıpkı Scala'nın Java bayt koduna derlendiği gibi Python bayt koduna derlenebilecek bir dil yazmak mümkündür. Etkileşimli modda, Python'un etkileşimli kabuğu yazılan komutunuzu bayt kodunda derler ve bu bayt kodunu yürütür. Eval ve exec kullanarak kendi kabuğunuzu yazabilir ve bir dizeyi bayt koduna dönüştürmek için compile () yerleşik işlevini kullanabilirsiniz.
Yalan Ryan

4
@Lie Ryan evet ama resmi olarak JVM'de olduğu gibi desteklenmiyor. Python'da, bytecode belgesiz bir uygulama detayıdır.
Antimon

159

Bu yazıda "sanal makine", Qemu veya Virtualbox gibi sistem sanal makinelerini değil, işlem sanal makinelerini ifade eder. Bir işlem sanal makinesi basitçe genel bir programlama ortamı sağlayan bir programdır - programlanabilen bir program.

Java'nın hem bir sanal makine hem de bir tercümanı vardır ve Python'un bir sanal makine ve bir tercümanı vardır. "Sanal makine" nin Java'da daha yaygın bir terim olması ve "yorumlayıcı" nın Python'da daha yaygın bir terim olmasının iki dil arasındaki büyük farkla ilgisi vardır: statik yazım (Java) ve dinamik yazım (Python). Bu bağlamda, "tür" ilkel veri türlerini ifade eder - verilerin bellek içi depolama boyutunu öneren türler. Java sanal makinesi bunu kolaylaştırır. Programlayıcının her değişkenin ilkel veri türünü belirtmesi gerekir. Bu, Java bayt kodu için yalnızca Java sanal makinesi tarafından yorumlanması ve yürütülmesi için değil, aynı zamanda makine yönergelerinde derlenmesi için de yeterli bilgi sağlar.. Python sanal makinesi, işlemde yer alan her değişken veya veri yapısı için ilkel veri türlerini belirlemek üzere her bir işlemin yürütülmesinden önce ek duraklatma görevini üstlenmesi bakımından daha karmaşıktır. Python, programcıyı ilkel veri türleri açısından düşünmekten kurtarır ve işlemlerin daha yüksek bir seviyede ifade edilmesini sağlar. Bu özgürlüğün bedeli performanstır. "Tercüman", Python için tercih edilen terimdir çünkü veri türlerini incelemek için duraklaması gerekir ve ayrıca dinamik olarak yazılan dillerin nispeten özlü sözdizimi etkileşimli arabirimler için iyi bir seçimdir. Etkileşimli bir Java arabirimi oluşturmak için teknik bir engel yoktur, ancak herhangi bir statik olarak yazılan kodu etkileşimli olarak yazmaya çalışmak sıkıcı olacaktır, bu yüzden bu şekilde yapılmaz.

Java dünyasında, sanal makine şovu çalar çünkü makine talimatlarında derlenebilecek bir dilde yazılmış programları çalıştırır ve sonuç hız ve kaynak verimliliğidir. Java bayt kodu, göreceli olarak, derlenmiş programların performansına yaklaşan Java sanal makinesi tarafından yürütülebilir. Bunun nedeni bayt kodunda ilkel veri türü bilgilerinin bulunmasıdır. Java sanal makinesi Java'yı kendi kategorisine yerleştirir:

taşınabilir yorumlanmış statik tip dil

Bir sonraki en yakın şey LLVM'dir, ancak LLVM farklı bir düzeyde çalışır:

taşınabilir yorumlanmış montaj dili

"Bayt kodu" terimi hem Java hem de Python'da kullanılır, ancak tüm bayt kodları eşit oluşturulmaz. bytecode sadece derleyiciler / tercümanlar tarafından kullanılan ara diller için kullanılan genel bir terimdir. Gcc gibi C derleyicileri bile işi tamamlamak için bir ara dil (veya birkaç) kullanır. Java bayt kodu, ilkel veri türleri hakkında bilgi içerirken Python bayt kodu içermez. Bu bağlamda, Python (ve Bash, Perl, Ruby, vb.) Sanal makine gerçekten Java sanal makinesinden daha yavaştır, ya da daha çok daha fazla işi vardır. Farklı bayt kodu formatlarında hangi bilgilerin bulunduğunu düşünmek yararlıdır:

  • llvm: cpu kayıtları
  • Java: ilkel veri türleri
  • Python: kullanıcı tanımlı türler

Gerçek dünyaya benzetmek için: LLVM atomlarla çalışır, Java sanal makinesi moleküller ile çalışır ve Python sanal makinesi malzemelerle çalışır. Her şey nihayetinde atom altı parçacıklara (gerçek makine işlemleri) ayrılması gerektiğinden, Python sanal makinesi en karmaşık göreve sahiptir.

Statik olarak yazılan dillerin yorumlayıcıları / derleyicileri, dinamik olarak yazılan dillerin yorumlayıcılarının / derleyicilerinin sahip olduğu bagajlara sahip değildir. Statik olarak yazılan dillerin programcıları, getirinin performans olduğu gevşekliği almalıdır. Bununla birlikte, tüm belirsiz olmayan fonksiyonlar gizlice deterministik olduğu gibi, dinamik olarak yazılmış tüm diller de gizlice statik olarak yazılır. Bu nedenle iki dil ailesi arasındaki performans farklılıkları, Python'un adını HAL 9000 olarak değiştirdiği zaman boyunca dengelenmelidir.

Python gibi dinamik dillerin sanal makineleri, idealize edilmiş bir mantıksal makine uygular ve herhangi bir gerçek fiziksel donanıma çok yakından karşılık gelmez. Buna karşılık, Java sanal makinesi, klasik bir C derleyicisine işlevsellik bakımından daha benzerdir, ancak makine talimatlarını yaymak yerine yerleşik rutinleri yürütür. Python'da, bir tamsayı, bir grup öznitelik ve ona bağlı yöntemler içeren bir Python nesnesidir. Java'da int, genellikle 32 olan belirlenmiş bir bit sayısıdır. Gerçekten adil bir karşılaştırma değildir. Python tamsayıları gerçekten Java Integer sınıfıyla karşılaştırılmalıdır. Java'nın "int" ilkel veri türü Python dilindeki hiçbir şeyle karşılaştırılamaz, çünkü Python dili basitçe bu ilkel katmanından yoksundur ve Python bayt kodu da öyle.

Java değişkenleri açıkça yazıldığından, Jython performansı gibi bir şeyin cPython ile aynı balo sahasında olması beklenebilir . Öte yandan, Python'da uygulanan bir Java sanal makinesinin çamurdan daha yavaş olduğu neredeyse garanti edilmektedir. Ve Ruby, Perl, vb. Daha iyi ücret bekliyoruz. Bunu yapmak için tasarlanmamışlardı. Dinamik bir dilde programlama adı verilen "script" için tasarlanmışlardır.

Sanal bir makinede gerçekleşen her işlemin sonunda gerçek donanıma çarpması gerekir. Sanal makineler, herhangi bir mantıksal işlem kombinasyonunu yürütmek için yeterince genel olan önceden derlenmiş rutinler içerir. Bir sanal makine yeni makine talimatları yayınlamıyor olabilir, ancak kesinlikle alışılmış karmaşık dizilerde kendi rutinlerini tekrar tekrar yürütüyor. Java sanal makinesi, Python sanal makinesi ve diğer tüm genel amaçlı sanal makineler hayal edebileceğiniz herhangi bir mantığı gerçekleştirmek için eşgüdümlü olmaları açısından eşittir, ancak hangi görevler açısından farklıdırlar ve programcıya hangi görevleri bıraktıkları.

Python için Psyco tam bir Python sanal makinesi değil, normal Python sanal makinesini birkaç kod satırı derleyebileceğini düşündüğü noktalarda ele geçiren tam zamanında bir derleyici - esas olarak bazı ilkel türlerini düşündüğü yerlerde döngüler değişken, her yinelemede değer değişse bile sabit kalır. Bu durumda, normal sanal makinenin sürekli tür belirlemesinden vazgeçebilir. Yine de, tipi Psyco'nun ayaklarının altından çıkarmamak için biraz dikkatli olmalısınız. Bununla birlikte, Pysco, türün değişmeyeceğinden tamamen emin değilse, normal sanal makineye geri dönmeyi bilir.

Hikayenin ahlakı, ilkel veri türü bilgilerinin bir derleyici / sanal makine için gerçekten yararlı olmasıdır.

Son olarak, her şeyi perspektife koymak için şunu düşünün: Bir Python yorumlayıcı / sanal makine tarafından Java üzerinde çalışan bir Java yorumlayıcı / sanal makine üzerinde çalışan bir iPhone üzerinde çalışan bir qemu sanal makinede çalışan LLVM uygulanan bir Python programı.

permalink


1
trying to write any statically-typed code interactively would be tedious. OCaml ve Haskell'i biliyorsanız, statik olarak yazılan çok kısa diller olduğu için bunun doğru olmadığını göreceksiniz .
Matthias Braun

@MatthiasBraun Bu işlevsel dillerin özlü kod ürettiğini kabul edebilirim, ancak bu, etkileşimli mod için çok uygun oldukları anlamına gelmez. OCaml ve Haskell dinamik olarak lisp gibi yazıldıysa, varsaydığım etkileşimli mod için daha iyi çalışırlardı.
bombalar

58

Muhtemelen farklı terminolojinin bir nedeni, normalde python yorumlayıcı ham insan tarafından okunabilir kaynak kodunu beslemeyi ve bayt kodu ve tüm bunlar hakkında endişelenmemeyi düşünmesidir.

Java'da, açıkça bayt kodunu derlemeniz ve sonra VM'de kaynak kodunu değil, yalnızca bayt kodunu çalıştırmanız gerekir.

Python kapakların altında bir sanal makine kullansa da, kullanıcının bakış açısından, bu detay çoğu zaman göz ardı edilebilir.


1
Katılıyorum. Terminolojideki bu fark gerçekten son kullanıcı (geliştirici, yani) deneyimine gelir. Gerçek teknik farklılıklarla hiçbir ilgisi yoktur, çünkü teknik hat, varolmayacak kadar inanılmaz derecede bulanıktır.
Cody Brocious

1
+1: Ve - daha da önemlisi - anlamı nedir? Bu ayrım nedeniyle hangi programı yazamazsınız? Hangi yığın izlemesi sizi şaşırtıyor? Hangi kütüphane düzgün çalışmıyor?
S.Lott

@ S.Lott Çünkü meslektaşlarınızla tartışmak her zaman iyidir. ;)
Qix - MONICA

16

Tercüman , kaynak kodunu bazı etkili ara gösterimlere (koda) çevirir ve derhal yürütür.

Sanal Makine , yorumlayıcı sisteminin bir parçası olan bir derleyici tarafından oluşturulan depolanmış önceden derlenmiş kodu açıkça yürütür.

Sanal makinenin çok önemli bir özelliği, içeride çalışan yazılımın sanal makine tarafından sağlanan kaynaklarla sınırlı olmasıdır. Kesinlikle, sanal dünyasından çıkamaz. Uzak kod olan Java Uygulamalarının güvenli bir şekilde yürütülmesini düşünün.

Python durumunda, bu yazının yorumunda belirtildiği gibi pyc dosyalarını tutuyorsak , mekanizma daha çok bir VM gibi olur ve bu bayt kodu daha hızlı yürütülür - yine de yorumlanır, ancak daha bilgisayar dostu bir formdan . Buna bir bütün olarak bakarsak, PVM Python Yorumlayıcı'nın son adımıdır.

Sonuç olarak Python Tercüman'ı ifade ettiğimizde, bunu bir bütün olarak ifade ettiğimiz anlamına gelir ve PVM dediğimizde, bu sadece bir çalışma zamanı ortamı olan Python Tercümanının bir kısmından bahsettiğimiz anlamına gelir. Java'ya benzer şekilde, farklı kısımları farklı, JRE, JVM, JDK, vb.

Daha fazla bilgi için Wikipedia Girişi: Tercüman ve Sanal Makine . Henüz başka bir buraya . Burada uygulama sanal makinelerinin karşılaştırmasını bulabilirsiniz . Derleyiciler, Tercümanlar ve VM'ler arasındaki farkın anlaşılmasına yardımcı olur.


12

Yorumlayıcı terimi, önceki kabuk komut dosyası dillerine dayanan eski bir terimdir. "Kodlama dilleri" tam özellikli dillere dönüştükçe ve ilgili platformları daha sofistike ve korumalı hale geldikçe, sanal bir makine ile bir yorumlayıcı (Python anlamında) arasındaki fark çok küçük veya yoktur.

Python yorumlayıcısı, ayrı bir derleme adımı olmadan yürütülebileceği anlamında hala kabuk betiği ile aynı şekilde çalışır. Bunun ötesinde, Python'un tercümanı (veya Perl veya Ruby'nin) ve Java'nın sanal makinesi arasındaki farklar çoğunlukla uygulama detaylarıdır. (Java'nın Python'dan daha tamamen korumalı olduğunu iddia edebilir, ancak her ikisi de sonuçta temeldeki mimariye yerel bir C arayüzü üzerinden erişim sağlar.)


1
Java kodunu ayrı (kullanıcı tarafından görülebilir) derleme adımları olmadan çalıştırabilen java kabukları vardır.
Yalan Ryan

1
adı ver: D
Maciej Nowicki

11

" Neden Java Sanal Makinesi, ancak Python yorumlayıcısı? " Sorusuna derin bir cevap vermek için , derlemenin teorisi alanına tartışmanın başlangıç ​​noktasına dönelim.

Program derlemesinin tipik süreci sonraki adımları içerir:

  1. Sözcüksel analiz . Program metnini jeton adı verilen anlamlı "kelimelere" böler (işlemin bir parçası olarak tüm yorumlar, boşluklar, yeni satırlar vb. Kaldırılır, çünkü program davranışını etkilemezler). Sonuç, sıralı bir jeton akışıdır.
  2. Sözdizimi analizi . Sözde oluşturur soyut sözdizimi Ağacı (AST) jeton akımından. AST, jetonlar arasında ilişkiler kurar ve bunun sonucunda programın değerlendirme sırasını tanımlar.
  3. Anlamsal çözümleme . Programlama dilinin türleri ve semantik kuralları hakkında bilgiler kullanarak AST'nin anlamsal doğruluğunu doğrular. (Örneğin a = b + c, sözdizimi açısından doğru bir ifadedir, ancak semantik açıdan tamamen yanlışsa,a sabit bir nesne olarak bildirilmişse )
  4. Ara kod üretimi . AST'yi, makineden bağımsız "ilkel" işlemlerin doğrusal sıralı akışına serileştirir. Aslında, kod üreticisi AST'yi dolaşır ve değerlendirme adımlarının sırasını kaydeder. Sonuç olarak, programın ağaç benzeri sunumundan, program değerlendirme sırasının korunduğu çok daha basit liste benzeri sunum elde ederiz.
  5. Makine kodu üretimi . Makineden bağımsız "ilkel" bayt kodu biçimindeki program, belirli işlemci mimarisinin makine koduna çevrilir.

Tamam. Şimdi terimleri tanımlayalım.

Tercüman , bu kelimenin klasik anlamında, doğrudan program metninden üretilen AST'ye dayalı program değerlendirmesine dayalı olarak yürütmeyi üstlenir . Bu durumda, bir program kaynak kodu biçiminde dağıtılır ve yorumlayıcı, program metni tarafından, genellikle dinamik bir şekilde (deyim ya da satır satır) beslenir. Her girdi ifadesi için, tercüman AST'sini oluşturur ve derhal programın "durumunu" değiştirerek değerlendirir. Bu, betik dilleri tarafından gösterilen tipik bir davranıştır. Örneğin Bash, Windows CMD vb. Düşünün. Kavramsal olarak, Python da bu yolu benimser.

Yorumlayıcıda ara makineden bağımsız ikili bayt kodu oluşturma işleminde AST tabanlı yürütme adımını değiştirirsek, program yürütme sürecinin tamamını iki ayrı aşamaya böleriz: derleme ve yürütme. Bu durumda daha önce bir tercüman olan bir bytecode derleyicisi haline gelecektir, bu da programı metin biçiminden bir ikili forma dönüştürecektir . Sonra program bu ikili biçimde dağıtılır, ancak kaynak kodu biçiminde dağıtılmaz. Kullanıcı makinesinde bu bayt kodu, aslında bu bayt kodunu yorumlayan yeni bir varlığa - sanal makineye beslenir . Bu nedenle sanal makinelere bayt kodu yorumlayıcısı da denir . Ama dikkatinizi buraya koyun! Klasik bir tercümanmetin yorumlayıcısı , ancak sanal makine ikili bir yorumlayıcıdır ! Bu Java ve C # tarafından alınan bir yaklaşımdır.

Son olarak, makine kodu üretimini bytecode derleyicisine eklersek sonuçta klasik derleyici dediğimiz şeyi elde ederiz . Klasik bir derleyici, program kaynak kodunu belirli bir işlemcinin makine koduna dönüştürür . Bu makine kodu daha sonra herhangi bir ek arabuluculuk olmadan doğrudan hedef işlemcide yürütülebilir (herhangi bir tercüman veya metin tercümanı veya ikili tercüman olmadan).

Şimdi orijinal soruya geri dönelim ve Java ile Python'u düşünelim.

Java başlangıçta mümkün olduğunca az uygulama bağımlılığına sahip olacak şekilde tasarlanmıştır. Tasarımı "bir kez yaz, her yerde koş" ilkesine (WORA) dayanmaktadır. Bunu uygulamak için Java başlangıçta makineden bağımsız ikili bayt koduna derlenen bir programlama dili olarak tasarlandı ve daha sonra Java'yı yeniden derlemeye gerek kalmadan destekleyen tüm platformlarda yürütülebilir . Java'yı WORA tabanlı C ++ gibi düşünebilirsiniz . Aslında, Java C ++ 'ya Python gibi kodlama dillerinden daha yakındır . Ancak C ++ , Java'nın aksine içine derlenmiş üzere tasarlanmıştırC ++ makine kodunda derlenecek ve daha sonra doğrudan hedef işlemci tarafından yürütülecek şekilde tasarlanırken , daha sonra sanal makine ortamında yürütülen ikili bayt kodu.

Python başlangıçta komut dosyalarını (programlama dili kurallarına uygun olarak yazılmış metin biçimindeki programlar) yorumlayan bir tür komut dosyası programlama dili olarak tasarlanmıştır . Bu nedenle, Python başlangıçta Bash veya Windows CMD'nin yaptığı gibi tek satırlı komutların veya ifadelerin dinamik bir yorumunu destekledi. Aynı nedenden ötürü, Python'un ilk uygulamalarında bu tür bayt kodunun yürütülmesi için herhangi bir bayt kodu derleyici ve sanal makine yoktu , ancak başından beri Python , Python programını anlama ve değerlendirme yeteneğine sahip bir tercümana ihtiyaç duyuyordu. metnini .

Bu nedenle, tarihsel olarak, Java geliştiricileri bahsetmek eğiliminde Java Virtual Machine (başlangıçta, çünkü Java ait paket olarak geldi Java baytkodu derleyici ve bytecode yorumlayıcısı - JVM ve) Python geliştiricileri hakkında konuşmak eğiliminde Python başlangıçta çünkü (tercüman Python vardır herhangi bir sanal makine değil ve program metnini yürüten bir tür klasik metin yorumlayıcıydı derleme veya herhangi bir ikili kod biçimine dönüştürülmeden doğrudan ).

Şu anda, Python ayrıca kaputun altında sanal makineye sahiptir ve Python bayt kodunu derleyebilir ve yorumlayabilir. Ve bu gerçek karışıklığa ek bir yatırım yapar " Neden Java Sanal Makinesi değil Python yorumlayıcısı?"ve programların tam olarak aynı davranışı göstermesi ve eşit girdiden aynı çıktıyı üretmesi. Gözlemlenen tek fark program yürütme hızı ve yorumlayıcı tarafından tüketilen bellek miktarı olacaktır. Bu nedenle, Python'daki sanal makine dil tasarımının kaçınılmaz bir parçası değil, sadece büyük Python yorumlayıcısının isteğe bağlı bir uzantısıdır.

Java da benzer şekilde düşünülebilir. Kaputun altındaki Java bir JIT derleyicisine sahiptir ve Java sınıfının yöntemlerini hedef platformun makine koduna seçerek derleyebilir ve doğrudan çalıştırabilir. Fakat! Java hala bytecode yorumlamasını Java programının yürütülmesinin birincil yolu olarak kullanır. Yalnızca bir optimizasyon tekniği olarak kaputun altındaki sanal makineleri kullanan Python uygulamaları gibi, Java sanal makineleri de sadece optimizasyon amacıyla Just-In-Time derleyicilerini kullanır. Benzer şekilde, sadece makine kodunun Java bayt kodunun yorumlanmasından en az on kat daha hızlı yürütülmesi nedeniyle. Python örneğinde olduğu gibi, JVM başlığı altında JIT derleyicisinin varlığı hem Java dil tasarımcıları hem de Java program geliştiricileri için kesinlikle şeffaftır. Aynı Java programlama dili JVM tarafından JIT derleyicili veya JIT derleyicisiz uygulanabilir. Aynı şekilde, içinde JIT olan ve olmayan JVM'lerde aynı programlar yürütülebilir ve aynı programlar tam olarak aynı davranışı gösterecek ve her iki JVM'deki (JIT olan ve olmayan) eşit girdiden eşit olarak aynı çıktıyı üretecektir. Python örneğinde olduğu gibi, aralarında gözlemlenebilir tek fark, uygulama hızında ve JVM tarafından tüketilen bellek miktarında olacaktır. Ve son olarak, Python'da olduğu gibi, Java'daki JIT de dil tasarımının kaçınılmaz bir parçası değil, sadece büyük JVM uygulamalarının isteğe bağlı bir uzantısıdır. ve aynı programlar tam olarak aynı davranışı gösterecek ve her iki JVM'deki (JIT olan ve olmayan) eşit girdiden eşit olarak aynı çıktıyı üretecektir. Python örneğinde olduğu gibi, aralarında gözlemlenebilir tek fark, uygulama hızında ve JVM tarafından tüketilen bellek miktarında olacaktır. Ve son olarak, Python'da olduğu gibi, Java'daki JIT de dil tasarımının kaçınılmaz bir parçası değil, sadece büyük JVM uygulamalarının isteğe bağlı bir uzantısıdır. ve aynı programlar tam olarak aynı davranışı gösterecek ve her iki JVM'deki (JIT olan ve olmayan) eşit girdiden eşit olarak aynı çıktıyı üretecektir. Python örneğinde olduğu gibi, aralarında gözlemlenebilir tek fark, uygulama hızında ve JVM tarafından tüketilen bellek miktarında olacaktır. Ve son olarak, Python'da olduğu gibi, Java'daki JIT de dil tasarımının kaçınılmaz bir parçası değil, sadece büyük JVM uygulamalarının isteğe bağlı bir uzantısıdır.

Java ve Python sanal makinelerinin tasarımı ve uygulanması açısından, önemli ölçüde farklılık gösterirken, (dikkat!) Her ikisi de sanal makinelerde kalmaktadır. JVM, basit temel işlemlere ve yüksek komut gönderme maliyetine sahip düşük seviyeli bir sanal makineye bir örnektir. Python da, talimatların karmaşık davranışlar sergilediği ve talimat dağıtım maliyetinin o kadar önemli olmadığı yüksek seviyeli bir sanal makinedir. Java çok düşük soyutlama düzeyiyle çalışır. JVM, küçük iyi tanımlanmış ilkel tipler kümesinde çalışır ve bayt kodu talimatları ile yerel makine kodu talimatları arasında çok sıkı bir yazışma (tipik olarak bire bir) vardır. Aksine, Python sanal makine yüksek soyutlama seviyesinde çalışır, karmaşık veri tipleri (nesneler) ile çalışır ve geçici polimorfizmi destekler, bytecode talimatları, bir dizi çoklu yerel makine kodu talimatı ile temsil edilebilecek karmaşık davranışları ortaya çıkarır. Örneğin, Python sınırsız aralık matematiğini destekler. Bu nedenle Python VM, işlem sonucu makine kelimesini taşabilecek potansiyel olarak büyük tamsayılar için uzun aritmetiklerden faydalanmak zorunda kalır. Bu nedenle, Python'daki aritmetikler için bir bayt kodu talimatı Python VM içindeki fonksiyon çağrısına maruz kalabilirken, JVM aritmetik işlemi bir veya birkaç yerel makine talimatı ile ifade edilen basit bir operasyona maruz kalacaktır. Bu nedenle Python VM, işlem sonucu makine kelimesini taşabilecek potansiyel olarak büyük tamsayılar için uzun aritmetiklerden faydalanmak zorunda kalır. Bu nedenle, Python'daki aritmetikler için bir bayt kodu talimatı Python VM içindeki fonksiyon çağrısına maruz kalabilirken, JVM aritmetik işlemi bir veya birkaç yerel makine talimatı ile ifade edilen basit bir operasyona maruz kalacaktır. Bu nedenle Python VM, işlem sonucu makine kelimesini taşabilecek potansiyel olarak büyük tamsayılar için uzun aritmetiklerden faydalanmak zorunda kalır. Bu nedenle, Python'daki aritmetikler için bir bayt kodu talimatı Python VM içindeki fonksiyon çağrısına maruz kalabilirken, JVM aritmetik işlemi bir veya birkaç yerel makine talimatı ile ifade edilen basit bir operasyona maruz kalacaktır.

Sonuç olarak, sonraki sonuçları çıkarabiliriz. Java Sanal Makinesi ancak Python yorumlayıcısı:

  1. Sanal makine terimi ikili bayt kodu yorumlamasını, tercüman terimi ise program metni yorumlamasını varsayar.
  2. Tarihsel olarak, Java ikili bayt kodu yorumlaması için tasarlanmış ve uygulanmıştır ve Python başlangıçta program metni yorumlaması için tasarlanmış ve uygulanmıştır. Bu nedenle, "Java Sanal Makinesi" terimi, Java topluluğunda tarihseldir ve köklüdür. Ve benzer şekilde, "Python Tercüman" terimi Python topluluğunda tarihi ve iyi kurulmuş bir terimdir. İnsanlar geleneği uzatma ve daha önce kullanılan terimleri kullanma eğilimindedir.
  3. Son olarak, Java için, ikili bayt kodu yorumlama programların yürütülmesinin birincil yoludur, JIT derlemesi ise sadece isteğe bağlı ve şeffaf bir optimizasyondur. Ve Python için, şu anda, program metni yorumu Python programlarının yürütülmesinin birincil yoludur, Python VM bayt koduna derleme ise sadece isteğe bağlı ve şeffaf bir optimizasyondur.

Bu nedenle, hem Java hem de Python'da " Neden Java Sanal Makinesi, ancak Python yorumlayıcısı?" gibi karışıklığa yol açabilen ikili bayt kodu yorumlayıcıları olan sanal makineler bulunur . Burada kilit nokta, Python için sanal bir makinenin birincil ya da gerekli bir program yürütme aracı olmamasıdır; klasik metin yorumlayıcısının isteğe bağlı bir uzantısıdır. Öte yandan, sanal bir makine, Java programı yürütme ekosisteminin temel ve kaçınılmaz bir parçasıdır. Programlama dili tasarımı için statik veya dinamik yazma seçeneği yalnızca sanal makine soyutlama seviyesini etkiler, ancak sanal bir makineye gerek olup olmadığını dikte etmez. Her iki yazım sistemini kullanan diller, istenen yürütme modellerine bağlı olarak sanal makine ortamında derlenecek, yorumlanacak veya yürütülecek şekilde tasarlanabilir.


2
Bu resmi cevap IMHO olarak seçilmelidir.
Ravikanth Andhavarapu

"Hem Java hem de Python'da sanal makineler var ikili bytecode yorumlayıcılar." Dönemi.
stuartw

10

Aralarında gerçek bir fark yok, insanlar sadece yaratıcıların seçtiği sözleşmeleri takip ediyor.


3
Sana buraya bir kemik fırlatacağım çünkü bu muhtemelen gerçek cevap ve bit eksikliğine oy verdin.
vikingben

3

Python'un x86 için mevcut JIT derleyicileri olduğunu ve sorunu daha da karıştırdığını unutmayın. (Bkz. Psiko).

'Yorumlanmış bir dilin' daha katı bir yorumu, yalnızca VM'nin performans sorunlarını tartışırken faydalı olur, örneğin Python ile karşılaştırıldığında, Ruby, Python'dan farklı olarak yorumlanmış bir dil olduğu için daha yavaş olarak kabul edildi (diğer?) kelimeler, bağlam her şeydir.


1
Bu yanlış. Birincisi, "yorumlanmış dil" diye bir şey yoktur. Bir uygulamanın bir derleyici veya yorumlayıcı kullanıp kullanmadığı, dilin değil uygulamanın bir özelliğidir. İkincisi, 13 kadar Ruby uygulamasından, tam olarak 1 bir tercüman, diğerlerinin de derleyicileri var.
Jörg W Mittag

2
Üçüncüsü, Ruby yavaş değil. Hiçbir dil yavaş değildir, çünkü hız dilin bir özelliği değil, dil uygulamasıdır. 13 kadar Ruby uygulamasından bazıları 7 Python uygulamasından daha yavaş, bazıları daha hızlıdır.
Jörg W Mittag

Sanırım buradaki standart uygulamaları karşılaştırıyor Jörg. CPython ve Ruby (Resmi uygulamanın sadece Ruby olarak adlandırıldığını düşünüyorum).
James McMahon

Arafangion "standart" uygulamalara atıfta bulunsa da, bunu söylemeliydi. Ben bir Pythonista'yım ama uygulamalar konusunda Jörg ile hemfikir olduğum için "Dil X yavaş" biçimindeki herhangi bir ifadeden nefret ediyorum .
tzot

1
Tam da bu yüzden "öyleydi?" Dedim ve özellikle "yavaş" terimi. Hiçbir yerde Ruby'nin kendi içinde yavaş olduğunu söylemedim.
Arafangion

2

Python kodu bayt koduna derlemeden yorumlayabilir. Java yapamaz .

Python, derlenmiş dilin aksine yorumlanmış bir dildir, ancak bytecode derleyicisinin varlığı nedeniyle ayrım bulanık olabilir. Bu, kaynak dosyaların daha sonra çalıştırılan bir yürütülebilir dosya oluşturmadan doğrudan çalıştırılabileceği anlamına gelir.

(belgelerden).

Java, her tek dosya vardır bir şekilde toplanabilir, .classsonra JVM üzerinde çalışan dosyasında. Aksine, bu dosyaların sonraki kullanımlarını hızlandırmak için python ana komut dosyanız tarafından içe aktarılır.

Bununla birlikte, tipik durumda, python (en azından CPython) kodunun çoğu, JVM'lerle neredeyse aynı talimatlara sahip olan taklit bir yığın makinesinde çalışır, bu yüzden büyük bir fark yoktur.

Ancak bu asıl neden, java'nın başından beri kendisini "taşınabilir, yürütülebilir bayt kodu" ve python'un kendisini REPL ile dinamik, yorumlanmış bir dil olarak markalamasıdır. İsimler sopa!


0

Her şeyden önce, programlama veya bilgisayar biliminin genel olarak matematik olmadığını ve sık kullandığımız terimlerin çoğu için titiz tanımlarımız olmadığını anlamalısınız.

şimdi sorunuza:

Tercüman nedir (bilgisayar bilimlerinde)

Kaynak kodunu en küçük çalıştırılabilir birim ile çevirir ve daha sonra bu birimi yürütür.

sanal makine nedir

JVM durumunda sanal makine bir Tercüman, sınıf yükleyiciler, çöp toplayıcı, iplik zamanlayıcı, JIT derleyici ve daha birçok şey içeren bir yazılımdır.

gördüğünüz gibi tercüman bir parçasıdır veya JVM ve tüm JVM başka birçok bileşen içerdiğinden tercüman olarak adlandırılamaz.

Python hakkında neden "Tercüman" kelimesini kullanıyorsunuz?

Java ile derleme bölümü açıktır. Öte yandan python derleme ve yorumlama süreci hakkında java olarak açık değildir, son kullanıcının bakış açısından yorumlama python programlarını yürütmek için kullanılan tek mekanizmadır


0

Hayır, ikisi de bayt kodunu yorumlamıyor.

Python sadece pypy ile çalışıyorsanız bayt kodunu yorumlar. Aksi takdirde C'ye derlenir ve bu düzeyde yorumlanır.

Java bayt kodunu derler.


Cevabınıza herhangi bir kaynak verebilir misiniz?
Isuru Dilshan


Yığın Taşması ile ilgili sorun budur. Birisi sinir bozucu bir uyum var çünkü onlar çağrılır ve downvotes ile ifade eder.
Michael Tamillow

0

Bence ikisi arasındaki çizgiler bulanık, insanlar çoğunlukla "tercüman" kelimesinin anlamı ve dilin "tercüman ... derleyici" spektrumunun her iki yanında ne kadar yakın durduğunu tartışıyorlar. Ancak hiçbiri% 100 yapmaz. Spektrumun herhangi bir değeri olan Java veya Python uygulamasını yazmanın kolay olduğunu düşünüyorum.

Şu anda hem Java hem de Python'un sanal makineleri ve bayt kodu var, ancak biri somut değer boyutlarıyla (32 bit tamsayı gibi) çalışıyor, diğeri her çağrı için boyutu belirlemek zorunda, bence terimler arasındaki sınırı tanımlamıyor.

Python'un resmi olarak bayt kodunu tanımlamadığı ve sadece bellekte var olduğu argümanı da beni ikna etmiyor, çünkü sadece Python bayt kodunu tanıyacak cihazlar geliştirmeyi planladığım ve derleme kısmı tarayıcı JS makinesinde yapılacak.

Performans sadece somut uygulama ile ilgilidir. Onunla çalışabilmek için nesnenin boyutunu bilmemize gerek yoktur ve son olarak, çoğu durumda, temel tiplerle değil, yapılarla çalışırız. Python VM'yi, ifade hesaplaması sırasında her seferinde mevcut nesneyi yeniden kullanarak yeni nesne oluşturma ihtiyacını ortadan kaldıracak şekilde optimize etmek mümkündür. Bir kez yapıldıktan sonra, Java'nın parladığı iki tamsayının toplamını hesaplamak arasında küresel bir performans farkı yoktur.

İkisi arasında katil bir fark yoktur, sadece bazı uygulama nüansları ve son kullanıcıyla ilgisi olmayan optimizasyon eksikliği, belki de performans gecikmelerini fark etmeye başladığı noktada, ancak yine mimari sorun değil, uygulama meselesidir.


0

Python'un bayt kodu üretmesi gerekmediğini belirten gönderiler için bunun doğru olduğundan emin değilim. Python'daki tüm callables'ların .__code__.co_codebayt kodunu içeren bir niteliği olması gerekir . Sadece derlenmiş eserler kaydedilemeyebilir çünkü "derlenmiş değil" olarak adlandırmak için anlamlı bir neden görmüyorum; ve genellikle Python'da tasarım ile kaydedilmez, örneğin tüm kavrama girdisi için yeni bayt kodu derler, bu nedenle kavrama değişkeni kapsamının bir python betiği çalıştırma ve pdb kullanma arasında tutarlı olmaması compile(mode='exec, ...)ve derlenmemesinin nedeni budurcompile(mode='single', ...)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.