a. Java'nın bugünkü hızı C ++ ile karşılaştırıldığında nasıldır?
Ölçmek zor. Bir uygulamanın hızının büyük bir kısmı olan hafıza ayırıcısı Java ve C ++ 'da çok farklı algoritmalar olduğuna dikkat etmek önemlidir. Kollektörün deterministik olmayan doğası, C ++ 'nın deterministik bellek yönetimine kıyasla anlamlı bir performans verisi elde etmeyi son derece zorlaştırır, çünkü koleksiyoncunun hangi durumda olduğunu asla bilemezsiniz. Bu, bir kriter yazmanın çok zor olduğu anlamına gelir. Bu onları anlamlı şekilde karşılaştırabilir. Bazı bellek ayırma düzenleri bir GC ile çok daha hızlı çalışır, bazıları ise yerel bir tahsisatçı ile çok daha hızlı çalışır.
Ancak şunu söyleyeceğim, Java GC'nin her durumda hızlı çalışması gerektiğidir . Ancak, yerel bir tahsisatçı, daha uygun bir kişi için değiştirilebilir. Geçenlerde SO hakkında Dictionary
eşdeğer bir C # ' nın (makinemde 0.45 msn) neden çalıştırabileceği konusunda bir soru sordum.std::unordered_map
hangi idamda (makinemde 10ms). Ancak, tahsisatçı ve hasher'i daha uygun olanlar için değiştirerek, bu çalışma zamanını orijinal çalışma süresinin otuzda biri olan makinemde 0.34 ms'ye indirdim. Java ile bu tür bir özel optimizasyon gerçekleştirmeyi asla ümit edemezsiniz. Bunun gerçek bir fark yaratabileceği şeyin mükemmel bir örneği, diş açmaktır. TBB gibi yerel iplik kütüphaneleri, pek çok konu üzerinde birçok tahsis ile uğraşırken geleneksel tahsis edicilerden çok daha hızlı olan iplik önbellekleme tahsis edici sağlar.
Şimdi, birçok kişi JIT’deki gelişmeler ve JIT’in daha fazla bilgiye sahip olduğu hakkında konuşacak. Tabii, bu doğru. Ancak, bir C ++ derleyicisinin çekebileceği şeye uzaktan bile yaklaşmıyor, çünkü derleyicinin, son programın çalışma zamanı açısından sınırsız bir zaman ve çalışma alanı vardır. JIT'in programınızı en iyi şekilde nasıl optimize edeceğinizi düşünerek geçirdiği her döngü ve programın yürütmek için harcamadığı ve kendi bellek ihtiyaçları için kullanamadığı bir döngüdür.
Ek olarak, derleyici ve JIT optimizasyonlarının belirli optimizasyonları kanıtlayamadığı zamanlar da olacaktır - özellikle kaçış analizi gibi durumlarda. C ++ 'da, değer yine de yığında olduğundan, derleyicinin bunu gerçekleştirmesi gerekmez. Ayrıca, bitişik hafıza gibi basit şeyler vardır. C ++ 'da bir dizi tahsis ederseniz, o zaman tek ve bitişik bir dizi tahsis edersiniz. Java'da bir dizi ayırırsanız, o zaman hiç bitişik değildir, çünkü dizi yalnızca herhangi bir yere işaret edebilecek işaretçilerle doldurulur. Bu sadece çift indirmeler için bir bellek ve zaman yükü değil, aynı zamanda önbellek ek yükü için de geçerlidir. Bu tür bir şey Java'nın dil anlambiliminin basitçe eşdeğer C ++ kodundan daha yavaş olması gerektiğini zorlamasıdır.
Sonuçta benim kişisel deneyimim, Java'nın ortalama olarak C ++ hızının yarısı kadar olabileceği yönünde. Bununla birlikte, temelde farklı algoritmalar nedeniyle, performans tablolarını son derece kapsamlı bir kıyaslama paketi olmadan yedeklemenin gerçekçi bir yolu yoktur.
b. Java kullanarak modern bir AAA başlığı oluşturmak mümkün müdür?
Sanırım burada "oyun" demek ve bir şans değil. Öncelikle, mevcut tüm kütüphaneleri ve altyapı hedefini C ++ olarak sıfırdan her şeyi kendiniz yazmak zorunda kalacaksınız. Kendisini imkansız kılmamakla birlikte, kesinlikle olanaksızlığa kesinlikle katkıda bulunabilir. İkincisi, C ++ motorları bile mevcut konsolların minik hafıza kısıtlamalarına pek uymuyor - eğer JVM'ler bu konsollar için bile mevcutsa ve PC oyuncuları hafızaları için biraz daha fazlasını bekliyorlar. Performanslı AAA oyunları oluşturmak C ++ 'ta yeterince zor, Java ile nasıl başarılabileceğini anlamıyorum. Hiç kimse hiç derlenmemiş bir dilde geçirdiği önemli bir zaman ile bir AAA oyunu yazmadı. Bundan daha fazlası, sadece son derece hataya açık olurdu. Deterministik yıkım, örneğin GPU kaynakları ile uğraşırken ve Java’da
c. Java hangi alanlarda özellikle C ++ 'dan daha yavaştır? (örn. Sayı-ezme, grafik veya hemen her yer)
Kesinlikle her yere giderdim. Tüm Java nesnelerinin zorunlu referans niteliği, Java'nın C ++ 'dan çok daha fazla dolaylı ve referanslı olduğu anlamına gelir; örneğin daha önce dizilerle verdiğim bir örnek, aynı zamanda tüm üye nesneler için de geçerlidir. Bir C ++ derleyicisinin bir üye değişkeni sabit sürede aradığı durumlarda, bir Java çalışma zamanı başka bir işaretçiyi izlemelidir. Ne kadar çok giriş yaparsanız, o kadar yavaş sonuçlanır ve JIT'nin yapabileceği hiçbir şey yoktur.
C ++ 'ın bir parçayı neredeyse anında serbest bırakıp yeniden kullanabileceği durumlarda, Java'da koleksiyonu beklemelisiniz ve umarım bu parça önbellekten çıkmaz ve doğal olarak daha fazla bellek gerektiren daha düşük önbellek ve çağrı performansı anlamına gelir. Sonra boks ve unboxing gibi şeyler için semantics bakın. Java'da, int'ye başvuru yapmak istiyorsanız, dinamik olarak ayırmanız gerekir. Bu, C ++ anlambilimine kıyasla doğal bir atık.
O zaman jenerik problemin var. Java'da, genel nesneler üzerinde yalnızca çalışma zamanı devralma yoluyla işlem yapabilirsiniz. C ++ 'da şablonlar tam anlamıyla sıfır ek yüke sahiptir - Java eşleşemez. Bu, Java'daki tüm genel kodların doğal olarak C ++ 'daki genel bir eşdeğerden daha yavaş olduğu anlamına gelir.
Ve sonra Tanımsız Davranış'a geliyorsun. Herkes programları UB'yi sergilediğinde nefret ediyor ve herkes bunun olmasını istemiyor. Bununla birlikte, UB, Java'da asla bulunamayacak optimizasyonları temel olarak sağlar. UB'ye dayalı optimizasyonları açıklayan bu gönderiye bir göz atın . Davranışın tanımlanmaması, uygulamaların daha fazla optimizasyon yapabileceği ve C ++ 'da tanımlanmamış ancak Java'da tanımlanmış koşulları kontrol etmek için gereken kodu azalttığı anlamına gelir.
Temel olarak, Java anlambilimi, C ++ 'dan daha yavaş bir dil olduğunu belirtir.
Java şimdi derlenmiş bir dil mi yoksa yorumlanmış bir dil mi?
Bu iki gruba da hiç uymuyor. Derlenmiş bir dilden çok daha fazla yorumlanmış bir dil gibi olduğunu söylememe rağmen, yönetilenlerin gerçekten kendi başlarına ayrı bir kategori olduğunu söyleyebilirim. Daha da önemlisi, hemen hemen sadece iki büyük yönetilen sistem var, JVM ve CLR ve “yönetilen” derken yeterince açık.
Java'nın ilk günlerden beri ele aldığı bazı önemli eksiklikler nelerdir?
Otomatik boks ve unboxing bildiğim tek şey. Jenerikler bazı problemleri çözerler ancak pek çoğundan uzaktırlar.
Java'nın henüz ele alınmaması gereken bazı önemli eksiklikler nelerdir?
Jenerikleri çok, çok zayıf. C # 'in jenerikliği oldukça güçlüydü - elbette, pek de şablonlar değil. Deterministik yıkım, diğer bir büyük eksikliktir. Herhangi bir lambda / kapatma şekli de büyük bir sorundur - Java'daki işlevsel bir API'yi unutabilirsiniz. Ve elbette, onlara ihtiyaç duyan bölgeler için her zaman performans sorunu var.