Java'nın C ++ 'dan daha hızlı olması neden mümkün olacak?


79

Bazen Java, ölçütlerde C ++ 'dan daha iyi performans gösterir. Tabii ki, bazen C ++ daha iyi performans gösteriyor.

Aşağıdaki linklere bakınız:

Fakat bu nasıl mümkün olabilir? Bayt kodunun yorumlanmasının derlenmiş bir dilden daha hızlı olabileceği aklıma geldi.

Birisi lütfen açıklayabilir mi? Teşekkürler!


2
Sen bir göz alabilir shootout.alioth.debian.org/u32/... / c ++ ... Bkz hızlı java üzerinde çalışan sorunların tür görmek sorunların desen değil, bu özel sorunlar ...
c0da

2
Bkz java yavaş bir imaja sahipti? bu konuyla ilgili birçok detay için.
Péter Török 26:11

11
Öyle kanun karşısında C ++ ile üretilen bir yürütülebilir ikili daha hızlı gerçekleştiren bir Java VM üretmek için (Bölüm 10.101.04.2c).
Mateen Ulhaq 26:11

1
@ muntoo Ne demek istiyorsun? Bölüm 10.101.04.2c neyin?
Yayla Mark

3
@HighlandMark Çevreye üye değilsin. Dairenin içinde neler olup bittiğini bilmiyorsunuz. Çember mutlaktır - çemberin yasaları doğanınkinin yerini alır. Çevreye meydan okuyamaz, sorgulayamazsınız. Ben çemberim ve çember benim.
Mateen Ulhaq

Yanıtlar:


108

İlk olarak, çoğu JVM bir derleyici içerir, bu nedenle "yorumlanan bayt kodu" aslında oldukça nadirdir (en azından kıyaslama kodunda - gerçek hayatta olduğu kadar nadir değildir, kodunuz genellikle çok sık tekrarlanan birkaç önemsiz döngüden daha fazladır) ).

İkincisi, söz konusu ölçütlerin çok sayıda önyargısı var gibi görünüyor (kasıtlı veya beceriksizce, gerçekten söyleyemem). Örneğin, yıllar önce, gönderdiğiniz bağlantılardan birine bağlı olan kaynak kodların bazılarına baktım. Bunun gibi bir kodu vardı:

  init0 = (int*)calloc(max_x,sizeof(int));
  init1 = (int*)calloc(max_x,sizeof(int));
  init2 = (int*)calloc(max_x,sizeof(int));
  for (x=0; x<max_x; x++) {
    init2[x] = 0;
    init1[x] = 0;
    init0[x] = 0;
  }

Yana callockullanmakta, sıfırlanmış oluyor bellek sağlar forbunu sıfır döngü tekrar açıkçası işe yaramaz. Bunu (eğer hafıza çalışıyorsa) yine de diğer verilerle doldurmak (ve sıfırlanmamasına bağımlı olmak yok) takip etti, böylece tüm sıfırlama yine de tamamen gereksizdi. Basit Yukarıdaki kodu değiştirilmesi malloc(bellek hizmet veriyorsa, oldukça geniş bir farkla) (herhangi bir akıllı kişi ile başlatmak için kullanılan olurdu gibi) yeterli Java sürüm yenmek için C ++ sürüm hızı geliştirilmiş.

methcallSon bağlantıda blog girişinde kullanılan ölçütü düşünün (başka bir örnek için) . İsim (ve nasıl işler daha görünebilir) rağmen, bu C ++ sürüm olduğu değil gerçekten hiç yöntem çağrısı yükü hakkında çok ölçme. Kodun kritik olduğu ortaya çıkan kısmı Toggle sınıfında:

class Toggle {
public:
    Toggle(bool start_state) : state(start_state) { }
    virtual ~Toggle() {  }
    bool value() {
        return(state);
    }
    virtual Toggle& activate() {
        state = !state;
        return(*this);
    }
    bool state;
};

Kritik kısım olduğu ortaya çıkıyor state = !state;. Biz devlet olarak kodlamak için kodunu değiştirmek ne olur düşünün intyerine ait bool:

class Toggle {
    enum names{ bfalse = -1, btrue = 1};
    const static names values[2];
    int state;

public:
    Toggle(bool start_state) : state(values[start_state]) 
    { }
    virtual ~Toggle() {  }
    bool value() {  return state==btrue;    }

    virtual Toggle& activate() {
        state = -state;
        return(*this);
    }
};

Bu küçük değişiklik genel hızı yaklaşık 5: 1 oranında artırır . Kriter olsa da amaçlanan gerçekte, o ölçme şeyin en yöntem çağrısı süresini ölçmek için arasında dönüştürme zamanı gelmişti intve bool. Orijinalin gösterdiği verimsizliğin talihsiz olduğuna kesinlikle katılıyorum - ancak gerçek kodda ne kadar nadir ortaya çıktığı göz önüne alındığında ve ne zaman ortaya çıkarsa düzeltilebilme kolaylığı göz önüne alındığında, zor bir zaman geçirdiğimi düşünüyorum. bunun anlamı olarak.

Herhangi birisinin söz konusu kriterleri yeniden çalıştırmaya karar vermesi durumunda, üreten Java sürümünde neredeyse eşit derecede önemsiz bir değişiklik yapıldığını da eklemeliyim. Son JVM hala yaptıklarını onaylamak için) Java sürümünde de oldukça önemli bir gelişme. Java sürümünde buna benzeyen bir NthToggle :: activate () var:

public Toggle activate() {
this.counter += 1;
if (this.counter >= this.count_max) {
    this.state = !this.state;
    this.counter = 0;
}
return(this);
}

Bunu this.statedoğrudan işlemek yerine temel işlevi çağırmak için değiştirmek , önemli ölçüde hız artışı sağlar (ancak değiştirilmiş C ++ sürümüne yetişmek için yeterli olmamakla birlikte).

Dolayısıyla, sonuçta yorumlanan bayt kodları ve şimdiye kadar gördüğüm en kötü kıyaslamaların bazıları hakkında yanlış bir varsayım var. İkisi de anlamlı bir sonuç vermiyor.

Benim kendi deneyimim, eşit derecede deneyimli programcıların optimizasyona eşit derecede dikkat etmesiyle, C ++ 'nın Java'yı sık sık yenmeyeceği - ama (en azından bu ikisi arasında), dil programcılar ve tasarım kadar nadiren fark yaratacaktır. Alıntılanan kriterler bize yazarlarının (in) yetkinliği / (dis) dürüstlüğü hakkında, kıyaslamada kullandıkları diller hakkında yaptıklarından daha fazlasını anlatır.

[Düzenleme: Yukarıda bir yerde belirtildiği gibi, ancak muhtemelen olması gerektiği gibi doğrudan belirtilmediği gibi, alıntı yaptığım sonuçlar, şu anda mevcut olan C ++ ve Java uygulamalarını kullanarak bu ~ 5 yıl önce test ettiğimde elde ettiğim sonuçlar. . Testleri mevcut uygulamalarla tekrar başlatmadım. Bununla birlikte, bir bakışta, kodun düzeltilmediğini, bu nedenle değiştirilebilecek tek şey derleyicinin koddaki sorunları örtme becerisi olacağını gösterir.]

Biz Java örneklerini görmezden gelirsek, ancak olduğu yorumlanır kodu (zor ve biraz alışılmadık olsa da) derlenmiş kod daha hızlı çalıştırmak için aslında mümkün.

Bunun olmasının genel yolu, yorumlanmakta olan kodun makine kodundan çok daha küçük olması veya kod önbelleğinden daha büyük veri önbelleği olan bir CPU'da çalışmasıdır.

Böyle bir durumda, küçük bir tercüman (örneğin, bir Forth uygulamasının iç tercümanı) tamamen kod önbelleğine sığabilir ve yorumladığı program tamamen veri önbelleğine sığabilir. Önbellek, genellikle en az 10 ve genellikle çok daha fazla bir faktörle ana bellekten daha hızlıdır (100 faktörü artık çok nadir değildir).

Öyleyse, önbellek ana bellekten N faktörü ile daha hızlıysa ve her bayt kodunu uygulamak için N makine kodu talimatından daha az sürerse, bayt kodunun kazanması gerekir (basitleştiriyorum, ancak genel fikrimin hala devam etmesi gerektiğini düşünüyorum). belirgin olun).


26
+1, tam teyp. Özellikle "dil, programcılar ve tasarım kadar nadiren fark yaratacaktır" - sık sık algoritmayı optimize edebileceğiniz problemler hakkında yanılıyorsunuzdur; örneğin, en iyi derleyicinin alabileceğinden çok daha fazlasını sağlayacak büyük-O'yu geliştirmek.
schnaader

1
“Herhangi birisinin söz konusu kriterleri tekrar çalıştırmaya karar vermesi durumunda ...” YAPMAYIN! 2005 yılında bu eski görevler atıldı ve şu anda benchmarklar oyununda gösterilen görevlerle değiştirildi. Herkes sonra bazı programlar yeniden çalıştırmak isterse kriterler oyun ana sayfası gösterilen cari görevler için geçerli programlarını yeniden çalıştırın shootout.alioth.debian.org
igouy

@igouy: Bazı insanlar koştukları kriterlerden elde edilen sonuçları basitçe onaylamak / reddetmek isteyebilir, en azından gerçeğe en az düzeyde ilişki sağlamak için gerekli olan minimum düzeltme. Aynı zamanda, temel olarak haklısınız: Söz konusu kriterler o kadar kötü ki, en bariz hataları düzeltmek pek işe yaramayacak.
Jerry Coffin

İşte bu yüzden, 2005 yılında, tekrar benchmark oyununda gösterilen görevlerle atıldılar ve değiştirildiler. Daha iyisini bilmeyen insanlar eski programları yeniden çalıştırırlar.
igouy

13
+1 İnsanların C ++ 'ı C veya Java tarzında kodlamasını ve ardından Java'nın üstün olduğunu belirtmesini istemiyorum. feragatname: Ben herhangi bir dile üstün gelmiyorum, fakat başka bir dile tam olarak uygun bir tarzda crappy C ++ kodu yazmak her iki dili de karşılaştırılabilir yapmıyor.
Christian Rau

111

El ile haddelenmiş C / C ++ uzmanı tarafından sınırsız sürelerle en az Java kadar hızlı veya daha hızlı olacak. Sonuçta, Java'nın kendisi C / C ++ dilinde yazılmıştır, böylece yeterli mühendislik çalışması için Java'nın yaptığı her şeyi yapabilirsiniz.

Ancak pratikte, Java aşağıdaki nedenlerden dolayı genellikle çok hızlı çalışır:

  • JIT derlemesi - Java sınıfları bayt kodu olarak saklansa da, bu (genellikle) program başlarken JIT derleyicisi tarafından yerel koda derlenir. Derlendikten sonra, saf yerel koddur - bu nedenle teorik olarak, program yeterince uzun bir süre çalıştıktan sonra (yani tüm JIT derlemesi yapıldıktan sonra) derlenmiş C / C ++ 'ın yanı sıra derlenmesi de beklenebilir.
  • Java'da çöp toplama işlemi son derece hızlı ve verimli - Hotspot GC, muhtemelen dünyadaki en iyi genel GC uygulamasıdır. Bu Sun ve diğer şirketler tarafından yıllarca süren uzman çabasının bir sonucudur. Hemen hemen C / C ++ 'da kullandığınız tüm karmaşık bellek yönetim sistemleri daha da kötüleşecektir. Elbette C / C ++ 'da oldukça hızlı / hafif temel bellek yönetimi şemaları yazabilirsiniz, ancak neredeyse tam bir GC sistemi kadar çok yönlü olmazlar. Çoğu modern sistem karmaşık bellek yönetimine ihtiyaç duyduğundan Java, gerçek dünyadaki durumlar için büyük bir avantaja sahiptir.
  • Daha iyi bir platform hedeflemesi - (JIT derleme vb) uygulaması başlatmak-up derleme geciktirerek Java derleyici bildiği gerçeği yararlanabilirsiniz kesin o yürütülen bir işlemci. Bu, bir "en düşük ortak payda" işlemci talimat setini hedeflemesi gereken önceden derlenmiş C / C ++ kodunda yapamayacağınız çok yararlı optimizasyonları sağlayabilir.
  • Çalışma zamanı istatistikleri - Çalışma zamanında JIT derlemesi yapıldığından, program yürütülürken daha iyi optimizasyonlar sağlayan (örneğin, belirli bir dalın alınma olasılığını bilmek) istatistikler toplayabilir. Bu, Java JIT derleyicilerinin C / C ++ derleyicilere göre daha iyi kod üretmesini sağlayabilir (önceden en muhtemel dalı "genellikle" yanlış olan bir varsayım "tahmin etmek" zorundadır).
  • Çok iyi kitaplıklar - Java çalışma zamanı, iyi performans gösteren çok iyi yazılmış bir çok kitaplık içerir (özellikle sunucu tarafı uygulamalar için). Genellikle bunlar, kendiniz yazabileceğinizden veya C / C ++ için kolayca edinebileceğinizden daha iyidir.

Aynı zamanda C / C ++ 'ın da bazı avantajları vardır:

  • Gelişmiş optimizasyonlar yapmak için daha fazla zaman - C / C ++ derlemesi bir kez yapılır ve bu nedenle, bunu yapılandırırsanız gelişmiş optimizasyonlar yapmak için önemli miktarda zaman harcayabilir. Java'nın aynı şeyi yapmasının teorik bir nedeni yoktur, ancak uygulamada Java'nın nispeten hızlı bir şekilde JIT kodunu derlemesini istersiniz, bu nedenle JIT derleyicisi "daha basit" optimizasyonlara odaklanma eğilimindedir.
  • Bayt kodunda açıklanamayan yönergeler - Java bayt kodu tamamen genel amaçlı olsa da, bayt kodunda yapamayacağınız düşük bir düzeyde yapabileceğiniz bazı şeyler vardır (denetlenmeyen işaretçi aritmetiği iyi bir örnektir!). (Ab) bu ​​tür püf noktaları kullanarak bazı performans avantajları elde edebilirsiniz.
  • Daha az "güvenlik" kısıtlaması - Java, programların güvenli ve güvenilir olmasını sağlamak için bazı ek çalışmalar yapmaktadır. Örnekler, dizilerdeki sınır kontrolleri, belirli eşzamanlılık garantileri, boş işaretçi kontrolleri, yayınlarda güvenliği yazın, vb. Olabilir.

Genel olarak, tüm:

  • Java ve C / C ++ benzer hızlara ulaşabilir
  • C / C ++ muhtemelen zorlu koşullarda çok ufak bir öneme sahip (örneğin, AAA oyun geliştiricilerin hala tercih etmeleri şaşırtıcı değil)
  • Uygulamada yukarıda listelenen farklı faktörlerin sizin uygulamanız için nasıl dengelendiğine bağlı olacaktır.

9
"C ++ 'ta optimizasyon için daha fazla zaman" reklamı: Bu , Sunucu VM'yi seçtiğinizde Oracle VM'nin yaptığı değişikliklerden biridir : Uzun vadede daha yüksek performans elde etmek için daha yüksek bir başlangıç ​​maliyeti kabul eder. Bununla birlikte, Client VM, optimum başlangıç ​​zamanı için ayarlandı. Yani bu ayrım bile var içinde Java.
Joachim Sauer

8
-1: Bir C ++ derleyicisi çok optimize edilmiş bir ikiliyi oluşturmak için çok daha fazla zaman alabilir (saatlerce, tam anlamıyla, büyük bir kütüphane için). Java JIT derleyicisinin "sunucu" sürümü bile çok fazla zaman alabilir. Java JIT derleyicisinin, Tüm Program Optimizasyonunu MS C ++ derleyicisinin yaptığı gibi yapabileceğinden şüpheliyim.
quant_dev

20
@quant_dev: elbette, ama cevabımda C ++ avantajı olarak söylediğim tam olarak bu değil mi (gelişmiş optimizasyon için daha fazla zaman)? Peki neden -1?
mikera

13
Çöp toplama, Java için bir hız avantajı değildir. Ne yaptığınızı bilmeyen bir C ++ programcısıysanız sadece hız avantajı. Kontrol ettiğiniz tek şey ne kadar hızlı tahsis edebileceğinizi, o zaman evet, çöp toplayıcı kazanacak. Bununla birlikte, genel program performansı, belleği manuel olarak yöneterek yine de daha iyi yapılabilir.
Billy ONeal

4
... Fakat C ++ ile, her zaman teorik olarak bir C ++ programının ham hızını korurken çalışma zamanında benzer dal optimizasyonları yapan bir "JIT benzeri katman" koyabilirsiniz. (Teorik olarak. :()
Mateen Ulhaq 26:11

19

Java çalışma zamanı isnt bytecode yorumlama. Aksine, Tam Zamanlı Derleme olarak adlandırılanları kullanır . Temel olarak, program çalıştırıldığında, bayt kodunu alır ve belirli bir CPU için optimize edilmiş yerel koda dönüştürür.


Uygulamada, evet. Prensip olarak, bağlıdır - bytecode tercümanları tarafından kullanılan erken Java sanal makineleri ve yeterince zor görünüyorsa muhtemelen hala bytecode tercüman VM'leri bulabilirsiniz.
Steve314

10
@ Steve314: ama tamamen yorumlama VM'lerin olmaz C ++ daha iyi performans olanlar, bu yüzden bu soruya gerçekten alakalı değildir.
Joachim Sauer

JIT derleyicisi, statik olarak derlenen kodla mümkün olmayan, kodun belirli kullanımı için dinamik olarak da optimize edilebilir.
starblue

2
@starblue, peki, statik bir derleme ile bir şekilde mümkündür - profil kılavuzlu optimizasyona bakınız.
SK-mantık

18

Her şey eşit olmak diyebilirsin: hayır, Java asla daha hızlı olmamalı . Java'yı her zaman C ++ 'dan sıfırdan uygulayabilir ve böylece en az iyi performans elde edebilirsiniz. Ancak uygulamada:

  • JIT , son kullanıcının makinesindeki kodu derler ve çalıştığı CPU için optimize edilmesini sağlar. Derleme için bir ek yük varken, yoğun uygulamalar için iyi bir sonuç verebilir. Genellikle gerçek hayat programları, kullandığınız CPU için derlenmez.
  • Java derleyicisi işleri otomatik olarak bir C ++ derleyicisinden daha iyi duruma getirmede daha iyi olabilir. Ya da olmayabilir, ama gerçek dünyada, işler her zaman mükemmel değildir.
  • Performans davranışı, çöp toplama gibi diğer faktörlere bağlı olarak değişebilir. C ++ 'da, genellikle bir nesneyle yapıldığında derhal yıkıcıyı çağırırsınız. Java'da, gerçek imhayı geciktirerek referansı bırakmanız yeterlidir. Bu, performans açısından ne burada ne de orada olmayan bir farkın başka bir örneğidir. Elbette, GC'yi C ++ 'ta uygulayabileceğinizi ve bununla bitebileceğini iddia edebilirsiniz, ancak gerçek şu ki, az sayıda insanın yapabildiği / yapabildiği şey.

Bir yana, bu bana 80'ler / 90'larda C ile ilgili tartışmayı hatırlatıyor. Herkes "C montaj kadar hızlı olabilir mi?" Diye merak ediyordu. Temel olarak cevap şuydu: kağıda hayır, ama gerçekte C derleyicisi montaj programcılarının% 90'ından daha verimli bir kod yarattı (aslında biraz olgunlaştığında).


2
GC ile ilgili olarak, GC sadece nesnelerin imhasını geciktiremez (uzun vadede önemli olmamalıdır); Gerçek şu ki, modern GC'lerde, kısa ömürlü nesnelerin tahsisi / dağıtılması, Java'da C ++ 'a kıyasla oldukça ucuz.
Péter Török 26:11

@ PéterTörök evet, haklısın, iyi nokta.
Daniel B

9
@ PéterTörök Ancak C ++ 'da, kısa ömürlü nesneler çoğu zaman yığına yerleştirilir ve bu da sırayla herhangi bir GC-ed yığın Java'nın kullanabileceğinden çok daha hızlıdır.
quant_dev

@quant_dev, bir diğer önemli GC efektini unuttun: kompaktlaşma. Bu yüzden hangi yolun daha hızlı olduğundan o kadar emin olmazdım.
SK-mantık

3
@DonalFellows C ++ ile hafıza yönetimi konusunda endişelenmem gerektiğini nereden çıkardınız? Çoğu zaman bilmiyorum. Uygulamanız gereken, Java'dan farklı, basit kalıplar var, ancak bu kadar.
quant_dev

10

Ancak tahsisat hafıza yönetiminin sadece yarısıdır - tahsisat diğer yarısıdır. Çoğu nesne için doğrudan çöp toplama maliyetinin - sıfır olduğu ortaya çıktı. Bunun nedeni, bir kopya toplayıcının ölü nesneleri ziyaret etmek veya kopyalamak zorunda kalmaması, yalnızca canlı olanları olmasıdır. Böylece tahsis edildikten kısa bir süre sonra çöp haline gelen nesneler, toplama döngüsüne hiçbir iş yükü kazandırmaz.

...

JVM'ler, yalnızca geliştiricinin bildiğini varsayarsak kullandığımız şeyleri bulmakta şaşırtıcı derecede iyidir. JVM'nin yığın tahsisi ve yığın tahsisi arasında durum bazında seçmesine izin vererek, programcının yığında mı yoksa yığında mı tahsis edip etmeyeceği konusunda agonize etmesine gerek kalmadan yığın tahsisinin performans avantajlarını elde edebiliriz.

http://www.ibm.com/developerworks/java/library/j-jtp09275/index.html


Bu, tüm resmin sadece küçük bir kısmı, ancak yine de oldukça alakalı.
Joachim Sauer

2
Bunun özünün nasıl olduğunu seviyorum: Java noobs içindir, sihirli GC'ye güven, daha iyi bilir.
Morg.

1
@Morg: Ya da bu şekilde okuyabilirsin: Java, zamanını bit çevirme ve manuel bellek yönetimi ile zamanını harcamak yerine işleri bitirmeyi seven insanlar içindir.
Landei

4
@Landei Java’nın uzun ömürlü, yaygın olarak kullanılan herhangi bir kod temeli yazılması durumunda, yorumunuzun çok daha güvenilir olduğunu düşünüyorum. Benim dünyamda, gerçek işletim sistemleri C'ye yazılır, postgreSQL C'ye yazılır, tıpkı yeniden yazılması gerçekten acı vericidir. Java, daha az yetenekli kişilerin sürülerde program yapmasını ve somut sonuçlara ulaşmasını sağlamak için (ve hatta resmi sürümdür).
Morg.

1
@Morg Ben sadece işletim sistemi üzerinde duruldu göründüğü çok garip buluyorum. Bu, birkaç nedenden ötürü, iyi bir önlem olamaz. Birincisi, işletim sistemlerinin gereksinimleri diğer yazılımlardan çok daha farklıdır, ikincisi de Panda thumb ilkesine sahipsiniz (başka bir dilde eksiksiz bir işletim sistemi yazmak isteyen, eğer çalışıyorsa ve hatta ücretsiz alternatifler varsa kendi işletim sistemini yazmak isteyen?) ve üçüncü diğer yazılımlar işletim sisteminin özelliklerini kullanır, bu nedenle bir disk sürücüsü, görev yöneticisi vb. yazmaya hiç gerek yoktur. Eğer daha iyi bir argüman sağlayamazsanız (tamamen işletim sistemlerine dayalı değil) bir nefret gibisiniz.
Landei

5

Tamamen optimize edilmiş bir Java programı nadiren tamamen optimize edilmiş bir C ++ programını geçerken, bellek yönetimi gibi şeyler arasındaki farklar, Java'ya deyimsel olarak uygulanmış birçok algoritmayı, deyimsel olarak C ++ dilinde uygulanan aynı algoritmaya göre daha hızlı hale getirebilir.

@ Jerry Coffin’in işaret ettiği gibi, basit değişikliklerin kodu çok daha hızlı hale getirebileceği birçok durum vardır - ancak performans iyileştirmenin faydalı olması için bir dilde veya diğerinde çok fazla kirli ince ayarlamalar yapılabilir. Muhtemelen , Java'nın C ++ 'dan daha iyi bir performans sergilediğini gösteren iyi bir kriter olarak görüyorsunuz .

Ayrıca, genellikle bu kadar önemli olmasa da, Java gibi bir JIT dilinin C ++ tarafından yapabileceği bazı performans optimizasyonları vardır. Java çalışma zamanı , kod derlendikten sonra geliştirmeler içerebilir , bu da JIT'in yeni (veya en azından farklı) CPU özelliklerinden yararlanmak için potansiyel olarak optimize edilmiş kod üretebileceği anlamına gelir. Bu nedenle, 10 yaşındaki bir Java ikili dosyası, 10 yaşındaki bir C ++ ikilisinden daha iyi performans gösterebilir.

Son olarak, büyük resimde tam tip güvenlik, çok nadir durumlarda, aşırı performans iyileştirmeleri sunabilir. Neredeyse tamamen C # tabanlı bir dilde yazılmış deneysel bir işletim sistemi olan tekillik , donanım süreci sınırlarına veya pahalı bağlam anahtarlarına gerek olmadığından işlemlerde daha hızlı iletişim kurar ve çok görevlidir.


5

Tim Holloway tarafından JavaRanch'ta gönderildi:

İşte ilkel bir örnek: Makinalar matematiksel olarak belirlenmiş çevrimlerde çalıştırıldığında, bir dal talimatı tipik olarak 2 farklı zamanlamaya sahipti. Biri dal alındığı zaman, biri dal alınmadığı zaman içindir. Genellikle şube dışı durum daha hızlıydı. Açıkçası, bu, hangi durumun daha yaygın olduğu bilgisine dayanarak mantığı en iyi duruma getirebileceğiniz anlamına geliyordu (“bildiğimiz” şeyin her zaman gerçekte olan şey olmadığı kısıtına tabi).

JIT yeniden derlemesi bunu bir adım daha ileri götürür. Gerçek zamanlı kullanımı izler ve en yaygın durum olan şeye dayanarak mantığı çevirir. İş yükü değişirse tekrar çevirin. Statik olarak derlenmiş kod bunu yapamaz. Java, bazen elle ayarlanmış meclis / C / C ++ kodunu bu şekilde gerçekleştirebilir.

Kaynak: http://www.coderanch.com/t/547458/Performance/java/Ahead-Time-vs-Just-time


3
Ve bir kez daha, bu yanlış / eksik. Profil güdümlü optimizasyona sahip statik derleyiciler bunu tanıyabilir.
Konrad Rudolph

2
Konrad, statik derleyiciler mevcut iş yüküne göre mantığı çevirebiliyor mu? Anladığım kadarıyla, statik derleyiciler bir kez kod üretir ve sonsuza dek aynı kalır.
Thiago Negri

2
Mevcut iş yükü, hayır. Ancak tipik iş yükü. Profil güdümlü optimizasyon programınızın tipik yük altında nasıl çalıştığını analiz eder ve HotSpot JIT'in yaptığı gibi etkin noktaları buna göre optimize eder.
Konrad Rudolph

4

Bunun sebebi, Java kodunuzu çalıştırırken, C ++ proramınızı oluştururken açık bir şekilde göstermek yerine, makine kodunu üreten son adımın JVM içinde şeffaf olarak gerçekleşmesidir .

Modern JVM'lerin mümkün olduğu kadar hızlı hale getirmek için anında yerel makine koduna geçerken bayt kodunu derlemek için oldukça fazla zaman harcadığını düşünmelisiniz. Bu, JVM'nin çalışmakta olan programın profil verilerini bilerek daha da iyi olabilecek her türlü derleyici püf noktasını yapmasını sağlar.

Sadece otomatik olarak bir alıcıyı içine yerleştirmek gibi bir şey, böylece bir JUMP-RETURN'in sadece bir değer elde etmek için gerek duyulmaması, işleri hızlandırır.

Ancak, hızlı programlara gerçekten izin veren şey, daha sonra daha iyi temizlik yapmaktır. Java'daki çöp toplama mekanizması, C'deki manuel malloksuzdan daha hızlıdır . Birçok modern malloksuz uygulama, altında bir çöp toplayıcı kullanır.


Bu gömülü malzemenin JVM'nin başlatılmasını daha iyi ve daha iyi kodun yakalama şansı elde edene kadar yavaşlatacağını unutmayın.

1
"Birçok modern malloc içermeyen uygulama, altında bir çöp toplayıcı kullanır." Gerçekten mi? Daha fazlasını bilmek isterim; Herhangi bir referansınız var mı?
Sean McMillan

Teşekkür ederim. JVM'nin artık çalıştırılabilir kodu derleyen tam zamanında bir derleyici içermediğini, ancak çalışan kodu profilleyen ve sonuç olarak daha da iyileştiren bir etkin nokta derleyici içerdiğini söylemenin bir yolunu bulmaya çalışıyordum. C ++ gibi bir kerelik bir derleyici buna uymak için mücadele ediyor.
Yayla Mark

@SeanMcMillan, malloc içermeyen uygulamaların performansı hakkında bir süre önce en hızlı olanın altında bir çöp toplayıcı kullandığı söylenen bir analiz gördüm. Nerede okuduğumu hatırlayamıyorum.

BDW muhafazakar GC miydi?
Demi

4

Kısa cevap - öyle değil. Unut gitsin, konu ateş veya tekerlek kadar eski. Java veya .NET, C / C ++ 'dan daha hızlı değildir ve olmayacaktır. İyileştirme hakkında düşünmeniz gerekmeyen çoğu görev için yeterince hızlı. Formlar ve SQL işleme gibi, ama bittiği yerde.

Karşılaştırmalar veya yetersiz geliştiriciler tarafından yazılmış küçük uygulamalar için evet, sonuçta Java / .NET'in muhtemelen yakın ve hatta belki daha hızlı olacağı sonucuna varılacak.

Gerçekte, yığına bellek tahsis etmek veya sadece memzon kullanmak gibi basit şeyler Java / .NET'i hemen öldürür.

Çöp toplayan dünya tüm muhasebeyle birlikte bir çeşit para kullanıyor. C'ye memzone ekle ve C tam orada daha hızlı olacak. Özellikle, Java-C "yüksek performanslı kod" karşılaştırma ölçütleri için şu şekildedir:

for(...)
{
alloc_memory//Allocating heap in a loop is verrry good, in't it?
zero_memory//Extra zeroing, we really need it in our performance code
do_stuff//something like memory[i]++
realloc//This is lovely speedup
strlen//loop through all memory, because storing string length is soo getting old
free//Java will do that outside out timing loop, but oh well, we're comparing apples to oranges here
}//loop 100000 times

Yığın tabanlı değişkenleri C / C ++ (ya da yeni yerleşim) 'de kullanmaya çalışın, tercüme ederler sub esp, 0xff, tek bir x86 komutudur, Java ile yenmek - yapamazsınız ...

Çoğu zaman Java'nın C ++ 'a karşı karşılaştırıldığı bankları görüyorum, bunun gibi olmama neden oluyor. Yanlış bellek ayırma stratejileri, rezervsiz kendiliğinden büyüyen kaplar, çok sayıda yeniler. Bu bile performans odaklı C / C ++ koduna yakın değil.

Ayrıca iyi bir okuma: https://days2011.scala-lang.org/sites/days2011/files/ws3-1-Hundt.pdf


1
Yanlış. Tamamen yanlış. Manuel bellek yönetiminizle kompaktlaştırıcı bir GC'den daha iyi performans sağlayamazsınız. Naif referans sayımı, uygun bir mark'n ağlamasından daha iyi olamaz. Karmaşık bir hafıza yönetimine gelir gelmez, C ++ bir geciktiricidir.
SK-mantık

3
@ SK-Mantık: Yanlış, memzones veya yığın tahsisi ile hiçbir ALL tahsis veya tahsisat yok. Bir hafıza bloğun var ve yazıyorsun. Bloğu eşzamanlılık koruması InterlockedExchange vb. Gibi değişken değişkenli olarak ücretsiz olarak işaretleyin ve bir sonraki iş parçacığı, verileri boş görüyorsa, işletim sistemi için hafızaya gitmeden önceden tahsis edilmiş bloğa aktarır. Yığınla daha da kolaydır, tek istisna ile, yığına 50 MB alamazsınız. Ve bu nesne ömrü sadece {} içindedir.
Kodlayıcı

2
@ SK-mantık: Derleyiciler önce doğrudur, performans ikincidir. Arama motorları, veritabanı motorları, gerçek zamanlı işlem sistemleri, oyunlar, performansı kritik olarak değerlendirdiğim şeylerdi. Ve bunların çoğu yassı yapılara dayanıyor. Her iki durumda da, derleyiciler çoğunlukla C / C ++ ile yazılmıştır. Özel tahsisatçılarla sanırım. Sonra tekrar, rammap üzerinde ağaç veya liste öğelerini kullanmakta bir sorun görmüyorum. Siz sadece yerleşimi yeni kullanın. Bunda fazla karmaşıklık yok.
Kodlayıcı

3
@ SK-mantık: Çok daha hızlı değil, gördüğüm her .NET / Java uygulaması, her zaman daha yavaş olduğu ve gerçek bir domuz olduğu ortaya çıktı. Yönetilen uygulamanın SANE C / C ++ koduna yeniden yazılması, daha temiz ve daha hafif bir uygulama ile sonuçlandı. Yönetilen uygulamalar her zaman ağırdır. Bkz. VS2010 vs 2008. Aynı veri yapıları, ancak VS2010 bir HOG'dir. Doğru yazılmış C / C ++ uygulamaları genellikle milisaniyede açılır ve açılış ekranlarında sıkışıp kalmaz, aynı zamanda daha az bellek tüketir. Tek dezavantajı, akılda donanım aklınızda bulundurmanız gerektiği ve birçok insanın bugünlerde nasıl olduğunu bilmediği. Yönetilen bir şansı olan sadece kriterler var.
Kodlayıcı

2
fıkra kanıtlarınız sayılmaz. Uygun kriterler gerçek farkı gösterir. Özellikle hantal ve alt-sınıf GUI kütüphanelerine bağlı olan GUI uygulamalarına atıfta bulunmanız gariptir. Ve, daha önemlisi - teoride, doğru şekilde uygulanan bir GC için performans sınırı çok daha yüksektir.
SK-mantık

2

Gerçek şu ki, her ikisi de, programcının tam olarak ne söylediğini yapan, programcının tam olarak programcının söylediği şekilde programcıya söylediklerini tam olarak yapan montajcılar. Performans farkları, tüm pratik amaçlara aykırı olacak kadar küçüktür.

Dil "yavaş" değil, programcı yavaş bir program yazdı. Çok nadiren, bir çalışmanın yazarı kendi eksenini taşlamadığı sürece, alternatif bir dilin en iyi yolunu kullanarak aynı şeyi yapan bir programdan (herhangi bir pratik amaç için) en iyi şekilde bir dilde en iyi şekilde yazılmış bir program olacaktır.

Açıkçası, zor gerçek zamanlı gömülü sistemler gibi ender rastlanan bir davaya gidecekseniz, dil seçimi bir fark yaratabilir, ancak bu ne kadar sıklıkla böyledir? ve bu durumlarda, doğru seçimin ne sıklıkla olduğu açıkça görülemez.


2
Teorik olarak, bir "ideal" JITting VM gerekir dinamik toplanan profil bilgilerine onun optimizasyon ayarlayarak statik olarak, kod derlenmiş çok daha üstündür. Uygulamada, JIT derleyicileri henüz o kadar akıllı değildir, ancak en azından daha büyük ve daha yavaş statik akranlarıyla olduğu gibi benzer kalitede bir kod üretme yeteneğine sahiptirler.
SK-mantık

2

Aşağıdaki linklere bakınız ... Fakat bu nasıl mümkün olabilir? Bayt kodunun yorumlanmasının derlenmiş bir dilden daha hızlı olabileceği aklıma geldi.

  1. Bu blog yazıları güvenilir kanıtlar sunuyor mu?
  2. Bu blog yazıları kesin kanıtlar sunuyor mu?
  3. Bu blog yazıları "yorumlanan bayt kodu" hakkında da kanıtlar sunuyor mu?

Keith Lea, size "açık kusurlar" olduğunu söyler ancak bu açık hatalar hakkında hiçbir şey yapmaz. 2005 yılında bu eski görevler atıldı ve şu anda benchmarklar oyununda gösterilen görevlerle değiştirildi .

Keith Lea, "şu anki eski Great Computer Language Shootout'tan C ++ ve Java için referans kodunu aldığını ve testleri yaptığını" ancak aslında yalnızca bu eski testlerden 25'inin 14'ü için ölçümler yaptığını söyledi .

Keith Lea şimdi yedi yıl önce blog yazısı ile hiçbir şey kanıtlamaya çalışmadığını söylüyor, ancak o zamanlar "Ben oldukça hızlı olduğunu bildiğimde Java’nın yavaş olduğunu söylediklerini duymaktan bıktım ..." dedi. O zamanlar kanıtlamaya çalıştığı bir şey vardı.

Christian Felde size "Ben kodu oluşturmadım, sadece testleri tekrar yaptım" diyor. sanki Keith Lea'nin seçtiği görevlerin ve programların ölçümlerini halka duyurma kararından sorumluydu.

25 minik küçük programın bile ölçümü kesin kanıt sağlıyor mu?

Bu ölçümler "karma mod" olarak çalışan programlar içindir. Java, Java yorumlu değildir - "HotSpot'un nasıl çalıştığını unutmayın." Java'nın "yorumlanan bayt kodu" ne kadar iyi çalıştığını kolayca öğrenebilirsiniz, çünkü Java'yı yalnızca bytecode yorumlamaya zorlayabilirsiniz - bazı Java programlarının -Xint seçeneğiyle veya onsuz çalıştırılması yeterlidir.


-1

Bu "yorumlu bytecode" un bu garip nosyonunun ne kadar yaygın olduğu beni eğlendiriyor. Sizler hiç JIT derlemesini duydunuz mu? Argümanınız Java'ya uygulanamaz.

Ancak, JVM'yi bir kenara bırakmak, doğrudan iş parçacıklı bir kodun ya da önemsiz bir bytecode yorumlamanın ağır derecede optimize edilmiş bir yerel koddan kolayca daha iyi performans gösterebileceği durumlar vardır. Açıklama oldukça basittir: bytecode oldukça kompakt olabilir ve aynı algoritmanın yerel bir kod sürümü tek bir yineleme için birkaç önbellek özlüyorsa sona erer.


Yorumun yaygınlığı, belki de bilgisayar bilimlerinde tecrübeli kişilerden kaynaklanıyor olabilir. Java sanal makinesi, java bayt kodunu kabul eden ve işlevsel olarak eşdeğer bir yerel program yazamadan, java bayt kodunu yerel olarak çalıştırabilen / çalıştıramayan / çalıştıramayan bir makinede çalıştırır. Ergo tercümandır. Önbelleğe alma tekniklerini JIT veya başka bir şekilde aklınıza gelebilecek herhangi bir ad verebilirsiniz, ancak tercüman tanımı tarafından bir tercümandır.
thiton

@Thiton, şans kendi CS-fu biraz zayıf. JVM, herhangi bir yorum yapmaz (sıcak noktalar için) - CS'den bahsetmeye cesaret eden biri olarak, bunun ne anlama geldiğini ve bir yorumlamanın operasyonel bir semantiğinin bir yerel kod çalıştırmanın ne kadar farklı olduğunu bilmeniz gerekir . Ancak, muhtemelen derlemeyi yorumlamadan ayırt etmek için yeterince CS bilmezsiniz.
SK-mantık

2
Umm, ancak bayt kodunun çalıştırılabilmesi için yerel koda dönüştürülmesi gerekiyor - Java bayt kodunu CPU'ya besleyemezsiniz. Yani boyut argümanı geçersiz.
quant_dev

@quant_dev, elbette - Bu davanın JVM ile tamamen alakasız olduğunu söyledim. Bu efekti çalıştırmak için çok daha basit bir bytecode motoruna ihtiyacınız olacak.
SK-mantık

-1

JIT, GC ve benzeri bir yana, C ++ Java'dan çok daha kolay bir şekilde halsiz hale getirilebilir. Bu kıyaslamalarda görünmez, ancak Java geliştiricisi ve C ++ geliştiricisi tarafından yazılmış aynı uygulama Java'da çok daha hızlı olabilir.

  • Operatör aşırı yükleniyor. "+" Veya "=" gibi her basit operatör güvenlik kontrolleri, disk işlemleri, günlüğe kaydetme, izleme ve profilleme yapan yüzlerce kod satırını arayabilir. Ve operatörleri aşırı yükledikten sonra, kullanımın nasıl yığıldığını fark etmeden doğal ve bolca kullanmanız için kullanımı çok kolaydır.
  • Şablonlar. Bunlar, hafıza kadar hızı etkilemez. Şablonların temkinsiz kullanımı, siz hiç fark etmeden milyonlarca satır kod (temel şablon için alternatifler) oluşturmanıza neden olacaktır. Ancak daha sonra ikili yükleme süreleri, bellek kullanımı, takas kullanımı - kıyaslamalara karşı da etkili olan her şey. RAM kullanımı çatıdan geçiyor.

Gelişmiş kalıtım kalıplarına gelince, bunlar oldukça benzer - C ++ bazı Java'ların yapmadığını ve bunun tersi olduğunu, ancak hepsinin de benzer, önemli bir ek yük getirdiğini gösteriyor. Nesne ağırlıklı programlamada özel bir C ++ avantajı yoktur.

Bir uyarı daha: GC, manuel olarak tahsisleri yönetmekten daha hızlı veya daha yavaş olabilir. Çok sayıda küçük nesne ayırırsanız, GC ortamında genellikle bir bellek parçası tahsis edilir ve parçaları yeni nesneler için gerektiği gibi gönderilir. Yönetilen - her nesne = ayrı tahsis önemli zaman alır. OTOH, bir kerede malloc () çok fazla bellek kullanırsanız ve daha sonra sadece nesnelerinize manuel olarak atarsanız veya birkaç büyük nesne örneği kullanırsanız, çok daha hızlı olabilirsiniz.


4
Her iki noktaya da katılmıyorum. Operatör veya yöntem kullanıp kullanmamanız önemli değil. Onların çoğalacaklarını söylüyorsunuz. Saçma - yöntemlerden daha fazla değil; ya onları aramanız gerek, gerek yok. Ve şablonlar, birden fazla kullanım için bu kodu tekrar yazmadan daha fazla kod oluşturmaz. Çalışma zamanı gönderiminden (sanal işlevler) daha fazla kod olabilir, ancak bu da önemsiz olacaktır: komut önbellek satırlarının performansı en sıkı döngülerde önemlidir ve burada yalnızca bir şablon başlatması kullanılacaktır, bu nedenle ilgili bellek baskısı yoktur şablonları nedeniyle.
Konrad Rudolph

Her zamanki zihniyet yöntemleri pahalı, operatörleri ucuz olmasıdır. Gerektiğinde yöntemleri, ne zaman zaman kazanmak ve optimize etmek istediğinizde operatörleri kullanırsınız. Teknik bir mesele değil, psikolojik - operatörlerin "daha ağır" olmaları değil, kullanımları çok daha kolay ve çok daha sık kullanılıyor. (artı, yaygın olarak kullanılan bir operatörü önceden var olan bir kodda aşırı yükleyebilirsiniz, orijinal olarak aynı hale getirir, artı bir ekstra - ve aniden tüm kod önemli ölçüde yavaşlar.
SF.

Bu psikolojik gerçeğin gerçek olduğunu itiraf ediyorum, ve öyle olsa bile, seçeneğiniz yok : bir işlevselliğe ihtiyacınız varsa, onu bir operatörde veya bir yöntemde saklanmalıysa kullanın. Psikoloji, semantiği seçtiğinizle ilgisizdir.
Konrad Rudolph

1
Tuzak soru. Bunu ikinci bir tahmin edemezdim, sonra ölçeceğim, sonra hareket edeceğim . Ben var asla o taktiği ile ilgili bir sorun vardı.
Konrad Rudolph

1
@KonradRudolph: Kodun açıklığı ve yazım kolaylığı söz konusu olduğunda, hatasız ve bakım yapılabilir hale geldiğinde bu durum geçerlidir. Algoritma uygulamasının verimliliği konusundaki nokta yine de duruyor: obj.fetchFromDatabase("key")aynı anahtar için beş kod satırı içinde üç kez yazıyorsanız, bu değeri bir kez alıp yerel bir değişkende önbelleğe almayı iki kez düşüneceksiniz. Eğer yazarsanız obj->"key"ile ->veritabanı getirme gibi davranmaya aşırı yüklenmesini, sadece operasyonun maliyeti belirgin olmadığı için geçmesine izin çok daha eğilimli konum.
SF.

-2

Bir şekilde Stack Exchange diğer yığınlarımı almıyor, bu yüzden ... ne yazık ki cevap yok ...

Ancak burada en çok oy alan ikinci cevap alçakgönüllü görüşüme göre yanlış bilgi dolu.

C / C ++ uzmanı tarafından elle haddelenmiş bir uygulama, her zaman bir Java uygulamasından çok daha hızlı olacak. 'Java ya da Faster kadar hızlı' yok. tam da aşağıda belirtilen öğelerden dolayı daha hızlı:

JIT derlemesi : Otomatik bir optimize edicinin uzman bir programcının akıllılarına sahip olmasını ve işlemcinin gerçekten çalıştıracağı kod ile niyet arasındaki bağlantıyı görmesini gerçekten bekliyor musunuz? Ayrıca, yaptığınız tüm JIT, önceden derlenmiş bir programa kıyasla zaman kaybıdır.

Çöp Toplama , bir programcının bırakmayı unutmuş olacağı kaynakları, az ya da çok verimli bir şekilde basitçe tahsis eden bir araçtır.

Açıkçası bu sadece bir uzmanın (terimi seçtiniz), C programcısı hafızasını ele almak için yapacağı şeyden daha yavaş olabilir (ve doğru yazılmış uygulamalarda sızıntı yok).

Performansı en iyi duruma getirilmiş bir C uygulaması çalıştığı CPU'yu bilir, üzerinde derlenir, yani performans için gereken tüm adımları tam olarak atmadığınız anlamına gelir?

Çalışma Zamanı İstatistikleri Bu benim bilgimin ötesinde, ancak C'deki bir uzmanın otomatik optimizasyondan daha zekice çıkması için yeterli şube tahmin bilgisine sahip olduğundan şüpheliyim -

Çok iyi kütüphaneler Java'daki kütüphaneler aracılığıyla kolayca bulunmayan pek çok optimize edilmemiş işlev vardır ve aynısı herhangi bir dilde geçerlidir, ancak en iyileştirilmiş kütüphaneler özellikle hesaplama için C dilinde yazılmıştır.

JVM , birçoğu yukarıda olan hem iyi şeyleri hem de genel çözümün tasarım açısından daha yavaş olduğunu ima eden bir soyutlama katmanıdır.

Genel olarak, tüm:

Java, birçok koruma, özellik ve araç içeren bir JVM'de çalıştığı için C / C ++ hızına asla erişemez.

C ++, bilgisayar yazılımı veya oyunlar için optimize edilmiş yazılımda kesin bir açıklığa sahiptir ve C ++ uygulamalarının en iyi Java uygulamalarının yalnızca ikinci sayfada görülebileceği noktaya kadar kodlama yarışmalarını kazandığını görmek olağandır.

Uygulamada C ++ bir oyuncak değildir ve çoğu modern dilin yapabileceği birçok hatadan kurtulmanıza izin vermez, ancak daha basit ve daha az güvenli olmakla, doğal olarak daha hızlıdır.

Sonuç olarak, çoğu insanın bu konuda iki sent vermediğini, sonuçta optimizasyonun sadece çok az sayıda şanslı geliştiriciye ayrılmış bir spor olduğunu ve performansın gerçekten endişe verici olduğu durumlar dışında olduğunu söylemek isterim. (donanımın 10 ile çarpılması size yardımcı olmayacak - veya en azından birkaç milyonu temsil edecekse), çoğu yönetici korumasız bir uygulama ve bir ton donanım tercih edecektir.


Tekrar. Çöp toplama sadece bir "serbest bırakan araç" değildir. GC yapılarınızı kompaktlaştırabilir. GC, zayıf referanslarınızı ele alabilir ve önbelleğe alma işleminizi bu şekilde dengelemenize yardımcı olabilir. Çok kademeli GC bir yığın tahsisini hacimli, yavaş veya daha ucuza getirir . Genel olarak herhangi bir manuel bellek yönetiminden çok daha hızlı olabilir - çünkü nesneleri manuel olarak yeniden konumlandıramazsınız. Bu yüzden, bütün akıl yürütme açıkça yanlış ve önyargılı. GC algoritmaları ve JIT optimizasyon yöntemleri konusundaki bilgileriniz çok sınırlıdır. newmalloc()
SK-mantık

4
Bu cevap, modern iyimserlerin neler yapabileceği hakkında yanlış anlamalar ile doludur. El ile optimize edilmiş kod buna karşı bir şansı yoktur. Ama sonra, C ++ da bir optimize derleyici vardır.
Konrad Rudolph

Bunu devlet olarak yorumunuz SK-mantık için teşekkürler, ama, GC olabilir çok daha hızlı genel olmak, belli bir durumda en hızlı ne olacağını bahsediyoruz, ve iyi görünüyor çoğu kişi bir şey olduğu GC can katılıyorum Bir programcının yapabildiğini ve hatta daha iyi yapabileceğini. Tabii ki doğrudan bellek erişiminiz olduğunda nesneleri manuel olarak yeniden konumlandırabilirsiniz .. lol. JVM içindekiler hakkındaki bilgilerim kesin olarak sınırlı ve Java kafalarının bana ışığı göstermesini bekliyorum, sadece GC'nin elle yapamayacağı şeyleri yapabilme konusundaki rastgele saçmalıklarını bana söylemeyin (lol ... GC'nin bile CPU talimatlarını kullanın;)).
Morg.

Konrad, modern optimize edicileri büyük ölçüde küçümsemediğime katılıyorum ... ancak elle optimize edilmiş kodu otomatik olarak optimize edilmiş koddan daha düşük olarak kabul etmenizi ilginç buluyorum. Derleyiciden bir insanın yapamayacağını ne görmesini beklersin?
Morg.

1
Sağ . -1 tuşuna basmaya devam edin, C ++ 'ın Java'dan daha hızlı olduğu gerçeğini değiştirmez. Modern derleyiciler hakkında çok fazla bir şey bilmeyebilirim, ancak bu ana noktaya bir fark yaratmıyor, ki bu doğru ve buradaki en çok oy alan cevaba aykırı. Başka neden C ++, HPC için GPU'larında nVidia için bir öncelik olacaktır. Neden tüm oyunlar C ++ 'ta yazılmalı, neden her DB motoru C de yazılsın?
Morg.

-4

Oyunlarda yeterince hızlı olmadığını söylemek için Java’da en az iki etkileyici mmo’nun yapıldığını gördüm. Oyun tasarımcıları C ++ 'ı diğer dillere göre daha fazla tercih ettikleri için, bunun yalnızca Java ile ilgili olmadığını söylemesi, programcıların hiçbir zaman diğer programlama dilleri / paradigmalarla gerçekten yüzleşmediği anlamına geliyor. C / C ++ kadar gelişmiş herhangi bir dilde, hatta Java bile teknik olarak hız argümanını karşılayan veya yenebilecek kodlar üretebilir. Tüm bunlar ve söylenenler, programcıların bildiği, hangi takımların en çok ve en önemlisi de neden bu araçları kullandıklarına bağlı olarak geliyor. Programlamanın oyun geliştirme yönünü ele aldığımız için, daha sonra argüman daha olmalı. Basitçe ' QA ve gerçek dünyada QA'yı karşılayan araçları kullanmaya karar veren bir işyerinde para ve zaman hakkında her şey, Java veya başka bir dilde C ++ 'ı seçmenin xx nedenleri üzerinde hiçbir ağırlığa sahip değildir. Bu sadece bir seri üretim kararı. En temel bilgi işlem algoritması seviyelerinde oynadığımız tek olanlar sıfır ve sıfırdır, hız argümanı şimdiye kadar oyunlara uygulanan en aptal argümanlardan biridir. Hız kazanmanın fena şekilde kazanılmasını istiyorsanız, programlama dillerini tamamen düşürün ve şimdiye kadarki en iyi avantaj olan derleme ile çalışın.


2
Bu metin duvarı, diğer cevaplarda daha önce belirtilmemiş bir şey ekliyor görünmüyor. Lütfen daha okunaklı olmak için cevabınızı düzenleyin ve lütfen cevabınızın diğer cevap tarafından belirtilmeyen noktalara değindiğinden emin olun. Aksi takdirde, lütfen bu noktaya yalnızca gürültü eklediği için yanıtınızı silmeyi düşünün.
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.