Aşağıdakilerin yalnızca yerel ve JIT derlemesi arasındaki farkı karşılaştırdığını ve herhangi bir dil veya çerçevenin özelliklerini kapsamadığını unutmayın. Bunun ötesinde belirli bir platform seçmek için meşru sebepler olabilir.
Biz yerel kod hızlıdır iddia, biz bahsediyoruz tipik kullanım durumunda hayır, mesela (anında sonuçlarla, bir JIT derlenmiş uygulamanın tipik kullanımı kullanıcı tarafından çalıştırılacak olan JIT derlenmiş kod, karşı doğal derlenmiş kod önce derleyici bekliyor). Bu durumda, kimsenin düz bir yüzle hak iddia edebileceğini sanmıyorum, JIT derlenmiş kodunun yerel kodla eşleşebileceğini veya yenebileceğini sanmıyorum.
Diyelim ki X dilinde yazılmış bir programımız olduğunu varsayalım ve onu yerel bir derleyici ile ve bir JIT derleyici ile derleyelim. Her iş akışı, aynı şekilde (Aşama -> Ara Temsil -> Makine Kodu -> Yürütme) genelleştirilebilecek aşamalara sahiptir. İkisi arasındaki en büyük fark, hangi aşamaların kullanıcı tarafından görüldüğü ve programcının gördüğü şeydir. Yerel derlemede, programcı yürütme aşamasından başka her şeyi görür, ancak JIT çözümünde yürütme işlemine ek olarak makine koduna derleme kullanıcı tarafından görülür.
A'nın B'den daha hızlı olduğu iddiası , programın çalışması için kullanıcı tarafından görüldüğü gibi geçen süreyi ifade eder . Her iki kod parçasının da Yürütme aşamasında aynı şekilde performans gösterdiğini varsayarsak, JIT iş akışının, kullanıcı için daha yavaş olduğunu varsaymalıyız, çünkü derlemenin T zamanını T> 0 olan makine koduna T zamanını görmesi gerekir. JIT iş akışının, kullanıcının yerel iş akışıyla aynı şekilde gerçekleştirilmesi olasılığına karşı, kullanıcıya, Yürütme + Derlemesi ile makine kodunun yürütülmesi süresini, Yürütme aşamasından daha düşük olacak şekilde azaltmalıyız. yerel iş akışının. Bu, JIT derlemesinde kodu yerel derlemeden daha iyi duruma getirmemiz gerektiği anlamına gelir.
Bununla birlikte, bu oldukça zordur, çünkü Yürütmeyi hızlandırmak için gerekli optimizasyonları gerçekleştirmek için, makine kodu aşamasında derlemeye daha fazla zaman harcamalıyız ve bu nedenle, optimize edilmiş kodun bir sonucu olarak kaydettiğimiz her zaman gerçekten kaybedilir. derlemeye ekleriz. Başka bir deyişle, JIT tabanlı bir çözümün "yavaşlığı" yalnızca JIT derlemesi için fazladan zaman harcadığından değil, bu derleme tarafından üretilen kod yerel bir çözümden daha yavaş çalışır.
Bir örnek kullanacağım: Kayıt tahsisi. Bellek erişimi, kayıt erişiminden binlerce kez daha yavaş olduğu için, mümkün olan her yerde kayıtları kullanmak istiyoruz ve mümkün olduğunca az bellek erişimine sahip olmak istiyoruz, ancak sınırlı sayıda kayıt sahibiz ve gerektiğinde belleği belleğe dökmeliyiz. Bir kayıt. Hesaplamak için 200ms alan bir kayıt tahsisat algoritması kullanırsak ve sonuç olarak 2ms yürütme süresinden tasarruf edersek - bir JIT derleyicisi için en iyi zamanı kullanmıyoruz. Yüksek derecede optimize edilmiş kod üretebilen Chaitin algoritması gibi çözümler uygun değildir.
JIT derleyicisinin rolü, derleme zamanı ile üretilen kodun kalitesi arasındaki en iyi dengeyi sağlamaktır, ancak kullanıcıyı derhal bekletmek istemediğiniz için hızlı derleme zamanı konusunda büyük önyargılara sahiptir. Yerel derleyici kodu en iyi duruma getirmede zaman zaman bağlı olmadığından, en iyi algoritmaları kullanmakta serbest olduğundan, JIT durumunda yürütülen kodun performansı daha yavaştır. Bir JIT derleyicisinin genel derleme + yürütmesinin yalnızca yerel olarak derlenen kod için yürütme süresini yenebilmesi olasılığı etkili bir şekilde 0'dır.
Ancak, VM'lerimiz yalnızca JIT derlemesiyle sınırlı değildir. Önceden derleme derleme teknikleri, önbellekleme, çalışırken değiştirme ve uyarlanabilir optimizasyonlar kullanıyorlar. Öyleyse performansın, kullanıcının gördüğü olduğu şeklini değiştirelim ve programı yürütmek için harcanan zamanı sınırlayalım (derlediğimizi varsayalım). Yürütme kodunu yerel derleyiciye eşdeğer (veya belki de daha iyi?) Etkin bir şekilde yapabiliriz. VM'ler için büyük bir iddia, yerel bir derleyiciden sonra daha iyi kalitede kod üretebilecekleri olabilir, çünkü daha fazla bilgiye erişim sağlayabiliyor - belirli bir işlevin ne sıklıkta yürütülebileceği gibi çalışan sürecinki. Sanal makine daha sonra çalışırken değiştirilebilir en temel koda adaptif optimizasyonlar uygulayabilir.
Yine de bu argümanla ilgili bir sorun var - bu, profil güdümlü optimizasyonun ve benzerlerinin VM'ler için benzersiz bir şey olduğunu varsayar, bu doğru değildir. Uygulamamızı profil etkinleştirilmiş olarak derleyerek, bilgileri kaydederek ve ardından uygulamayı bu profille yeniden derleyerek bunu yerel derlemeye de uygulayabiliriz. Kod değiştirme işleminin yalnızca bir JIT derleyicisinin yapabileceği bir şey olmadığını da belirtmek önemlidir, bunun için yerel kod için yapabiliriz - bunu yapmak için JIT tabanlı çözümler daha kolay erişilebilir ve geliştirici için çok daha kolay. Öyleyse asıl soru şudur: Bir VM bize yerel derlemenin yapamayacağı, kodumuzun performansını artırabilecek bir bilgi verebilir mi?
Kendim göremiyorum. İşlem daha fazla dahil olsa da, tipik bir VM tekniklerinin çoğunu da yerel koda uygulayabiliriz. Benzer şekilde, yerel bir derleyicinin tüm optimizasyonlarını AOT derlemesi veya uyarlamalı optimizasyonlar kullanan bir VM'ye geri uygulayabiliriz. Gerçek şu ki, yerel olarak çalışan kod ile VM'de çalışanlar arasındaki fark, inandığımız kadar büyük değil. Nihayetinde aynı sonuca götürürler, ancak oraya ulaşmak için farklı bir yaklaşım izlerler. VM, yerel derleyicinin başından itibaren beklediği (ve yinelemeli bir yaklaşımla geliştirilebilir) optimize edilmiş kod üretmek için yinelemeli bir yaklaşım kullanır.
Bir C ++ programcısı baştan beri optimizasyonlara ihtiyacı olduğunu savunabilir ve bir VM'nin nasıl yapılacağına karar vermesini beklememelidir. VM'lerimizdeki mevcut optimizasyon seviyesi, yerel derleyicilerin sunabileceğinden daha düşük olduğu için bu muhtemelen muhtemelen geçerli teknolojimizde geçerli bir nokta - ancak VM'lerimizdeki AOT çözümleri geliştiği zaman her zaman böyle olmayabilir.