C ++ performansı ile Java / C # karşılaştırması


119

Anladığım kadarıyla, C / C ++ belirli bir makine mimarisinde çalışmak için yerel kod üretir. Tersine, Java ve C # gibi diller, yerel mimariyi soyutlayan bir sanal makinenin üzerinde çalışır. Mantıksal olarak, Java veya C # için bu ara adımdan dolayı C ++ hızına uyması imkansız görünebilir, ancak bana en son derleyicilerin ("sıcak nokta") bu hıza ulaşabileceği veya hatta onu aşabileceği söylendi.

Belki de bu bir dil sorusundan çok bir derleyici sorusudur, ancak herhangi biri bu sanal makine dillerinden birinin ana dilden daha iyi performans göstermesinin nasıl mümkün olduğunu sade bir İngilizce ile açıklayabilir mi?


Java ve C #, çalışma zamanında mevcut olan kodu kullanarak uygulamanın gerçekte nasıl çalıştırıldığına bağlı olarak optimizasyon yapabilir. örneğin, paylaşılan bir kitaplıkta satır içi kod olabilir ve bu, program çalışırken gerçekten değişebilir ve yine de doğru olabilir.
Peter Lawrey

Bu cevaplarda pek çok
mantıksız

Yanıtlar:


178

Genel olarak, C # ve Java aynı derecede hızlı veya daha hızlı olabilir çünkü IL'nizi ilk çalıştırdığında derleyen bir derleyici olan JIT derleyici, C ++ derlenmiş bir programın makineyi sorgulayabildiği için yapamadığı optimizasyonları yapabilir. Makinenin Intel mi yoksa AMD mi olduğunu belirleyebilir; Pentium 4, Core Solo veya Core Duo; veya SSE4, vb. destekliyorsa

Bir C ++ programı, tüm makinelerde düzgün bir şekilde çalışabilmesi için genellikle karışık optimizasyonlarla önceden derlenmelidir, ancak tek bir konfigürasyon (yani işlemci, komut seti, diğer donanım) için olabileceği kadar optimize edilmemiştir.

Ek olarak, belirli dil özellikleri, C # ve Java'daki derleyicinin kodunuz hakkında, C / C ++ derleyicisinin yapması güvenli olmayan belirli bölümleri optimize etmesine izin veren varsayımlar yapmasına izin verir. İşaretçilere erişiminiz olduğunda, güvenli olmayan pek çok optimizasyon vardır.

Ayrıca Java ve C #, yığın ayırmalarını C ++ 'dan daha verimli bir şekilde yapabilir, çünkü çöp toplayıcı ile kodunuz arasındaki soyutlama katmanı, tüm yığın sıkıştırmasını aynı anda yapmasına izin verir (oldukça pahalı bir işlem).

Şimdi bir sonraki noktada Java adına konuşamıyorum, ancak C # örneğin yöntemin gövdesinin boş olduğunu bildiğinde aslında yöntemleri ve yöntem çağrılarını kaldıracağını biliyorum. Ve bu tür bir mantığı kodunuzun tamamında kullanacaktır.

Gördüğünüz gibi, belirli C # veya Java uygulamalarının daha hızlı olmasının birçok nedeni vardır.

Şimdi tüm bunların söylediği gibi, C ++ 'da, özellikle grafik alanında ve donanıma yakın olduğunuzda C # ile yapabileceğiniz her şeyi ortadan kaldıracak özel optimizasyonlar yapılabilir. İşaretçiler burada harikalar yaratır.

Yani ne yazdığına bağlı olarak, birini veya diğerini seçerim. Ancak donanıma bağlı olmayan bir şey yazıyorsanız (sürücü, video oyunu, vb.), C # 'ın performansı hakkında endişelenmem (yine Java hakkında konuşamam). İyi olacak.

Bir Java tarafı olan @Swati , iyi bir makaleye işaret ediyor:

https://www.ibm.com/developerworks/library/j-jtp09275


Muhakemeniz sahte - C ++ programları hedef mimarileri için oluşturulur, çalışma zamanında geçiş yapmaları gerekmez.
Justicle

3
@Justicle C ++ derleyicinizin farklı mimariler için sunacağı en iyi şey genellikle x86, x64, ARM ve diğeridir. Şimdi ona belirli özellikleri kullanmasını söyleyebilirsiniz (örneğin SSE2) ve eğer şanslıysanız, bu özellik mevcut değilse bazı yedek kodlar bile oluşturacaktır, ancak bu, elde edilebilecek en ince ayrıntıya kadar. Önbellek boyutlarına ve ne olduğuna bağlı olarak kesinlikle uzmanlaşma yok.
Voo

4
Bkz shootout.alioth.debian.org/u32/... bu teori örnekleri için değil oluyor.
Justicle

1
Dürüst olmak gerekirse, bu en kötü cevaplardan biri. O kadar temelsiz ki, onu tersine çevirebilirim. Çok fazla genelleme, çok fazla bilgisizlik (boş fonksiyonları optimize etmek gerçekten buzdağının görünen kısmıdır). Bir lüks C ++ derleyicisinde şunlar bulunur: Time. Başka bir lüks: Kontrol zorunlu değildir. Ancak stackoverflow.com/questions/145110/c-performance-vs-java-c/… adresinde daha fazlasını bulun .
Sebastian Mach

1
@OrionAdrian tamam şimdi tam çemberiz ... Bu teorinin gerçekleşmediği örnekleri için shootout.alioth.debian.org/u32/… bakın . Başka bir deyişle, belirsiz spekülatif açıklamalar yapmadan önce teorinizin doğruluğunun kanıtlanabileceğini bize gösterin .
Justicle

197

JIT ve Statik Derleyici

Önceki yazılarda belirtildiği gibi, JIT IL / bayt kodunu çalışma zamanında yerel koda derleyebilir. Bunun maliyetinden bahsedildi, ancak sonuca varılmadı:

JIT'in büyük bir sorunu, her şeyi derleyememesidir: JIT derlemesi zaman alır, bu nedenle JIT kodun yalnızca bazı kısımlarını derlerken, statik bir derleyici tam bir yerel ikili oluşturur: Bazı tür programlar için statik derleyici, JIT'den kolayca daha iyi performans gösterecektir.

Elbette, C # (veya Java veya VB) genellikle uygulanabilir ve sağlam bir çözüm üretmek için C ++ 'dan daha hızlıdır (eğer C ++' nın karmaşık anlambilimlere sahip olması ve C ++ standart kitaplığı, ilginç ve güçlü olmasına rağmen, tam sürümle karşılaştırıldığında oldukça zayıfsa) .NET veya Java'dan standart kitaplığın kapsamı), bu nedenle genellikle, C ++ ile .NET veya Java JIT arasındaki fark çoğu kullanıcı tarafından görülemez ve kritik olan ikili dosyalar için yine de C ++ işlemeyi çağırabilirsiniz. C # veya Java'dan (bu tür yerel çağrılar kendi başlarına oldukça maliyetli olsa bile) ...

C ++ meta programlama

Genellikle, C ++ çalışma zamanı kodunu C # veya Java'daki eşdeğeriyle karşılaştırdığınızı unutmayın. Ancak C ++, Java / C # 'dan daha iyi performans gösterebilen bir özelliğe sahiptir, yani şablon meta programlaması: Kod işleme derleme zamanında yapılacak (bu nedenle, derleme süresi büyük ölçüde artacak) ve sonuçta sıfır (veya neredeyse sıfır) çalışma zamanı elde edilecektir.

Henüz bu yüzden (Ben sadece kavramlarla oynadı ama o zamana kadar, fark JIT için yürütme saniye idi ve bu konuda gerçek bir hayat etkisini görmek var sıfır C ++ için), ama aslında şablon metaprograming değil yanında bu, bahsetmemiz olduğunu önemsiz ...

Düzenleme 2011-06-10: C ++ 'da, türlerle oynama, derleme zamanında yapılır, yani genel olmayan kodu çağıran genel kod üretilir (örneğin, dizeden T türüne genel bir ayrıştırıcı, tanıdığı T türleri için standart kitaplık API'sini çağırır, ve ayrıştırıcıyı kullanıcısı tarafından kolayca genişletilebilir hale getirmek) çok kolay ve çok etkilidir, oysa Java veya C # eşdeğerinin yazılması zahmetlidir ve türler derleme zamanında bilinse bile çalışma zamanında her zaman daha yavaş ve çözülür, Yani JIT'in her şeyi sıraya dizmesi tek umudunuz .

...

Düzenleme 2011-09-20: Blitz ++ ( Ana Sayfa , Wikipedia ) arkasındaki ekip bu şekilde gitti ve görünüşe göre hedefleri, FORTRAN'ın bilimsel hesaplamalardaki performansına, C ++ şablon metaprogramlama yoluyla, çalışma zamanı yürütmeden derleme süresine olabildiğince ilerleyerek ulaşmaktır. . "Yani ben henüz çok bu konuda gerçek bir hayat etkisini görmek var yukarıda yazdım parçası" görünüşte yapar Gerçek yaşamda var.

Yerel C ++ Bellek Kullanımı

C ++, Java / C # 'dan farklı bir bellek kullanımına sahiptir ve bu nedenle farklı avantajları / kusurları vardır.

JIT optimizasyonu ne olursa olsun, hiçbir şey belleğe doğrudan işaretçi erişimi kadar hızlı gidemez (bir an için işlemci önbelleklerini, vb. Görmezden gelelim). Dolayısıyla, bellekte bitişik veriler varsa, ona C ++ işaretçileri aracılığıyla erişmek (yani C işaretçileri ... Hadi Sezar'a sonunu verelim) Java / C # 'dan çok daha hızlı olacaktır. Ve C ++, RAII'ye sahiptir, bu da C # veya Java'dakinden çok daha kolay işlem yapar. C ++ 'nın usingnesnelerinin varlığını kapsaması gerekmez . Ve C ++ 'ın bir finallycümleciği yoktur. Bu bir hata değildir.

:-)

Ve C # ilkel benzeri yapılara rağmen, C ++ "yığın üzerindeki" nesneler, ayırma ve yok etme işlemlerinde hiçbir maliyeti olmayacak ve temizliği yapmak için bağımsız bir iş parçacığında çalışmak için GC'ye ihtiyaç duymayacaktır.

Bellek parçalanmasına gelince, 2008'deki bellek ayırıcılar, genellikle bir GC: C ++ tahsisi ile karşılaştırılan 1980'den kalma eski bellek ayırıcılar değildir, doğru, ancak daha sonra, bir Linux dosya sisteminde olduğu gibi: Kim sabit diske ihtiyaç duyar parçalanma olmadığında birleştirme? Doğru görev için doğru ayırıcıyı kullanmak, C ++ geliştirici araç setinin bir parçası olmalıdır. Şimdi, ayırıcı yazmak kolay değil ve o zaman çoğumuzun yapacak daha iyi işleri var ve çoğu kullanım için RAII veya GC fazlasıyla iyi.

Düzenleme 2011-10-04: Verimli ayırıcılar hakkında örnekler için: Windows platformlarında, Vista'dan beri Düşük Parçalanma Yığını varsayılan olarak etkindir. Önceki sürümlerde LFH, WinAPI HeapSetInformation işlevi çağrılarak etkinleştirilebilir . Diğer işletim sistemlerinde alternatif ayırıcılar sağlanmıştır (bkz.https://secure.wikimedia.org/wikipedia/en/wiki/Malloc liste için)

Şimdi, bellek modeli, çok çekirdekli ve çok iş parçacıklı teknolojinin yükselişi ile biraz daha karmaşık hale geliyor. Bu alanda sanırım .NET'in avantajı var ve Java üst sıralarda yer aldı bana söylendi. Bazı "çıplak metal" korsanlarının "makinenin yanında" kodunu övmesi kolaydır. Ama şimdi, derleyicinin işine izin vermektense elle daha iyi montaj yapmak çok daha zor. C ++ için, derleyici on yıldan beri genellikle hacker'dan daha iyi hale geldi. C # ve Java için bu daha da kolaydır.

Yine de, yeni standart C ++ 0x, C ++ derleyicilerine basit bir bellek modeli uygulayacak, bu da C ++ 'da etkili çoklu işlem / paralel / iş parçacığı kodunu standartlaştıracak (ve böylece basitleştirecek) ve derleyiciler için optimizasyonları daha kolay ve daha güvenli hale getirecek. Ama sonra, vaatlerinin doğru olup olmadığını birkaç yıl içinde göreceğiz.

C ++ / CLI ve C # / VB.NET

Not: Bu bölümde, C ++ / CLI, yani yerel C ++ değil .NET tarafından barındırılan C ++ 'dan bahsediyorum.

Geçen hafta .NET optimizasyonu üzerine bir eğitim aldım ve statik derleyicinin yine de çok önemli olduğunu keşfettim. JIT'den daha önemli.

C ++ / CLI'de (veya onun atası olan Managed C ++) derlenen aynı kod, C #'da üretilen aynı koddan (veya derleyicisi C # ile aynı IL'yi üreten VB.NET) kat kat daha hızlı olabilir.

Çünkü C ++ statik derleyici, zaten optimize edilmiş kod üretmek için C #'lardan çok daha iyiydi.

Örneğin, .NET'te işlev satır içi işlemi, bayt kodu uzunluğu 32 bayttan az veya buna eşit olan işlevlerle sınırlıdır. Bu nedenle, C #'daki bazı kodlar 40 baytlık bir erişimci üretecek ve bu, JIT tarafından hiçbir zaman satır içi olmayacak. C ++ / CLI'deki aynı kod, JIT tarafından satır içine alınacak 20 baytlık bir erişimci üretecektir.

Başka bir örnek, C # derleyicisi tarafından üretilen IL'de bahsedilmeye devam ederken, C ++ derleyicisi tarafından derlenen geçici değişkenlerdir. C ++ statik derleme optimizasyonu daha az kodla sonuçlanacak ve böylece yine daha agresif bir JIT optimizasyonuna izin verecektir.

Bunun nedeninin, C ++ / CLI derleyicisinin C ++ yerel derleyicinin geniş optimizasyon tekniklerinden yararlandığı gerçeği olduğu düşünülüyordu.

Sonuç

C ++ 'yı seviyorum.

Ama gördüğüm kadarıyla, C # veya Java hepsi daha iyi bir bahis. C ++ 'dan daha hızlı oldukları için değil, niteliklerini topladığınızda, daha üretken olurlar, daha az eğitime ihtiyaç duyarlar ve C ++' dan daha eksiksiz standart kitaplıklara sahip olurlar. Ve programların çoğunda olduğu gibi, hız farklılıkları (öyle ya da böyle) önemsiz olacaktır ...

Düzenle (2011-06-06)

C # /. NET konusundaki deneyimim

Şu anda 5 aylık neredeyse özel profesyonel C # kodlamam var (bu da zaten C ++ ve Java ile dolu CV'mi ve C ++ / CLI dokunuşunu ekliyor).

WinForms (Ahem ...) ve WCF (harika!) Ve WPF (Harika !!!! Hem XAML hem de ham C # aracılığıyla. WPF çok kolay Swing'in bununla kıyaslanamayacağına inanıyorum) ve C # 4.0.

Sonuç olarak, C # / Java'da çalışan bir kod üretmek C ++ 'dan daha kolay / daha hızlı olsa da, C # ile güçlü, güvenli ve sağlam bir kod üretmek (ve Java'da daha da zor) C ++' dan çok daha zordur. Sebepler çoktur, ancak şu şekilde özetlenebilir:

  1. Jenerikler, şablonlar kadar güçlü değildir ( sorunu anlamak için verimli bir genel Parse yöntemi (dizeden T'ye) veya boost :: lexical_cast'in C # 'da etkin bir eşdeğerini yazmaya çalışın )
  2. RAII eşsiz kalır ( GC hala sızıntı yapabilir (evet, bu sorunu halletmem gerekiyordu) ve sadece belleği idare edecek. C # 'ler bile usingkolay ve güçlü değildir çünkü doğru Dispose uygulamaları yazmak zordur )
  3. C # readonlyve Java finalgibi yararlı olarak hiçbir yerde vardır C ++ 'ınconst ( o yerleşik bir C ++ özelliği. Bu tür veriler ilginç bir çözümdür çalışırken siz muazzam iş olmadan C # salt okunur karmaşık veriler örneğin Düğümler (a Ağacı,) maruz hiçbir şekilde var, , ancak her şey değiştirilemez hale getirilemez, bu nedenle, şimdiye kadar yeterli bile değildir ).

Dolayısıyla, C #, çalışan bir şey istediğiniz sürece hoş bir dil olarak kalır, ancak her zaman ve güvenli bir şekilde çalışan bir şeyi istediğiniz anda sinir bozucu bir dildir .

Java, C # ile aynı sorunlara sahip olduğu için daha da sinir bozucu ve daha fazlası: C # usinganahtar kelimesinin eşdeğerinden yoksun olan çok yetenekli bir meslektaşım, kaynaklarının doğru bir şekilde serbest bırakıldığından emin olmak için çok zaman harcadı, oysa C ++ 'daki eşdeğer kolay oldu (yıkıcılar ve akıllı işaretçiler kullanarak).

Bu yüzden, C # / Java'nın üretkenlik kazancı çoğu kod için görülebilir ... koda olabildiğince mükemmel olması için ihtiyacınız olan güne kadar. O gün acıyı anlayacaksın. (sunucumuzdan ve GUI uygulamalarımızdan ne istediğine inanmayacaksınız ...).

Sunucu tarafı Java ve C ++ hakkında

Binanın diğer tarafında sunucu ekipleriyle (GUI ekibine dönmeden önce aralarında 2 yıl çalıştım) iletişimimi sürdürdüm ve ilginç bir şey öğrendim.

Geçtiğimiz yıllarda eğilim, Java sunucu uygulamalarının eski C ++ sunucu uygulamalarının yerini alması yönündeydi, çünkü Java çok sayıda çerçeve / araca sahip ve bakımı, dağıtımı vb. Kolay.

... Düşük gecikme sorunu son aylarda çirkin yüzünü gösterene kadar. Ardından, Java sunucu uygulamaları, yetenekli Java ekibimiz tarafından denenen optimizasyon ne olursa olsun, eski, gerçekten optimize edilmemiş C ++ sunucusuna karşı yarışı basit ve temiz bir şekilde kaybetti.

Şu anda karar, Java sunucularını, performansın hala önemliyken, düşük gecikme hedefiyle ilgilenmediği yerlerde ortak kullanım için tutmak ve düşük gecikme ve ultra düşük gecikme gereksinimleri için zaten daha hızlı olan C ++ sunucu uygulamalarını agresif bir şekilde optimize etmektir.

Sonuç

Hiçbir şey beklendiği kadar basit değil.

Java ve hatta daha fazlası C #, hızlı kod yazabileceğiniz ve çok kısa sürede sonuç alabileceğiniz kapsamlı standart kitaplıkları ve çerçeveleriyle harika dillerdir.

Ancak ham güce, güçlü ve sistematik optimizasyonlara, güçlü derleyici desteğine, güçlü dil özelliklerine ve mutlak güvenliğe ihtiyacınız olduğunda, Java ve C #, son eksik ancak kritik kalite yüzdelerini kazanmanızı zorlaştırır, rekabetin üzerinde kalmanız gerekir.

Ortalama kalitede kod üretmek için C # / Java'da C ++ 'dan daha az zamana ve daha az deneyimli geliştiricilere ihtiyaç duyuyormuşsunuz gibi, ancak diğer yandan, mükemmelden mükemmel kalitede koda ihtiyaç duyduğunuz anda, sonuçları almak aniden daha kolay ve daha hızlı hale geldi doğru C ++ içinde.

Tabii ki, bu benim kendi algım, belki de özel ihtiyaçlarımızla sınırlı.

Ama yine de bugün hem GUI ekiplerinde hem de sunucu tarafı ekiplerinde olan budur.

Tabii ki, yeni bir şey olursa bu gönderiyi güncelleyeceğim.

Düzenle (2011-06-22)

"Performans açısından, C ++ 'nın büyük bir farkla kazandığını görüyoruz. Bununla birlikte, aynı zamanda, çoğu, ortalama bir programcının erişemeyeceği bir karmaşıklık düzeyinde yapılan en kapsamlı ayarlama çabalarını da gerektiriyordu.

[...] Java sürümü muhtemelen uygulanması en basit olanıydı, ancak performans açısından analizi en zor olanıydı. Özellikle çöp toplama etrafındaki etkiler karmaşıktı ve ayarlanması çok zordu. "

Kaynaklar:

Düzenle (2011-09-20)

"Facebook'ta geçerli olan kelime, PHP ve Java kodunu optimize etmek için harcanan muazzam çabanın altını çizen ' makul bir şekilde yazılmış C ++ kodunun hızlı çalışmasıdır. Paradoksal olarak, C ++ kodu yazmak diğer dillerden daha zordur, ancak verimli kod [C ++ ile yazmak diğer dillere göre] çok daha kolay. "

- Herb Sutter de // yapı / , alıntı Andrei Alexandrescu

Kaynaklar:


8
5 aylık C # sonrasında düzenleme yaparsınız (şablonlar daha iyi, const daha iyi, RAII). +1. Bu üçü, C ++ (veya henüz vaktim olmayan D) için kişisel katil özelliklerim olmaya devam ediyor.
Sebastian Mach

"Kod işleme derleme zamanında yapılacaktır". Bu nedenle, şablon metaprogramlama yalnızca programda çalışır, bu genellikle böyle olmayan derleme zamanında kullanılabilir, örneğin, C ++ ile rekabet gücü yüksek bir düzenli ifade kitaplığı yazmak imkansızdır, çünkü çalışma zamanı kod üretme yeteneğinden yoksundur (önemli bir yönü) metaprogramming).
JD

"türlerle oynamak derleme zamanında yapılır ... Java veya C # 'deki eşdeğeri yazmak en iyi ihtimalle zahmetlidir ve türler derleme zamanında bilindiğinde bile çalışma zamanında her zaman daha yavaş ve çözümlenir". C # 'da, bu yalnızca başvuru türleri için doğrudur ve değer türleri için doğru değildir.
JD

1
"JIT optimizasyonu ne olursa olsun, hiçbir şey belleğe doğrudan işaretçi erişimi kadar hızlı gidemez ... Eğer bellekte bitişik veriye sahipseniz, C ++ işaretçileriyle (yani C işaretçileri ... Sezar'a hakkını verelim) zaman alır Java / C # "dan daha hızlı. İnsanlar, SciMark2 kıyaslamasından SOR testinde Java'nın C ++ 'yı geçtiğini gözlemlediler çünkü işaretçiler örtüşme ile ilgili optimizasyonları engelliyor. blogs.oracle.com/dagastine/entry/sun_java_is_faster_than
JD

Ayrıca .NET'in bağlamadan sonra dinamik olarak bağlantılı kitaplıklar arasında jeneriklerin tür uzmanlaşması yaptığını, ancak şablonların bağlanmadan önce çözümlenmesi gerektiğinden C ++ 'ın bunu yapamayacağını belirtmek gerekir. Ve tabii ki jeneriklerin şablonlara göre en büyük avantajı anlaşılır hata mesajlarıdır.
JD

48

Yönetilen ve yönetilmeyen performans hakkında konuştuğumda, Rico (ve Raymond) bir Çince / İngilizce sözlüğün C ++ ve C # sürümlerini karşılaştıran diziye işaret etmeyi seviyorum. Bu google araması kendi başınıza okumanıza izin verecek, ancak Rico'nun özetini beğendim.

Yani ezici yenilgimden utanıyor muyum? Zorlukla. Yönetilen kod, neredeyse hiç çaba harcamadan çok iyi bir sonuç aldı. Yönetilen Raymond'u yenmek için:

  • Kendi dosya G / Ç şeylerini yaz
  • Kendi string sınıfını yaz
  • Kendi ayırıcısını yaz
  • Kendi uluslararası haritasını yaz

Elbette bunu yapmak için mevcut alt düzey kitaplıkları kullandı, ancak bu hala çok fazla iş. Bir STL programından geriye kalanları arayabilir misin? Sanmıyorum, sonuçta hiçbir zaman sorun olmayan std :: vector sınıfını ve bulma işlevini koruduğunu düşünüyorum. Hemen hemen her şey gitti.

Yani, evet, CLR'yi kesinlikle yenebilirsiniz. Raymond programının daha da hızlı ilerlemesini sağlayabileceğini düşünüyorum.

İlginç bir şekilde, her iki programın dahili zamanlayıcıları tarafından bildirilen dosyayı ayrıştırma zamanı yaklaşık aynıdır - her biri için 30ms. Aradaki fark, tepede.

Benim için önemli olan, yönetilmeyen sürümün, orijinal yönetilmeyen kodun basit bir bağlantı noktası olan yönetilen sürümü yenmesi için 6 revizyon yapılması gerektiğidir. Performansın her bir parçasına ihtiyacınız varsa (ve bunu elde etmek için zamanınız ve uzmanlığınız varsa), yönetilmeden gitmeniz gerekecek, ancak benim için, 33'ün üzerindeki ilk sürümlerde sahip olduğum büyük avantaj sırasını alacağım % 6 kez denersem kazanıyorum.


3
bağlantı öldü, burada bahsedilen makale bulundu: blogs.msdn.com/b/ricom/archive/2005/05/10/416151.aspx
gjvdkamp

Öncelikle Raymond Chen'in koduna bakarsak, C ++ 'yı veya veri yapılarını çok iyi anlamadığı çok açık. C kodunun performans faydalarının olmadığı durumlarda bile, kodu neredeyse doğrudan düşük seviyeli C kodu için ulaşır (bu sadece bir tür güvensizlik ve belki de profil oluşturucuların nasıl kullanılacağına dair bilgi eksikliği gibi görünüyor). Ayrıca, bir sözlüğü uygulamanın algoritmik olarak en sağlam yolunu anlamada başarısız oldu (İsa aşkına std :: find'ı kullandı). Java, Python, C # vb. Hakkında iyi bir şey varsa - hepsi çok etkili sözlükler sağlar ...
stinky472

Denemeler ve hatta std :: map, C ++ ve hatta bir karma tablo için çok daha avantajlıdır. Son olarak, sözlük, üst düzey kitaplıklardan ve çerçevelerden en çok yararlanan program türüdür. Söz konusu kütüphaneler kadar dildeki farklılıkları göstermiyor (ki, mutlu bir şekilde şunu söyleyebilirim ki C # çok daha eksiksizdir ve görev için çok daha fazla araç sağlar). Büyük ölçekli bir matris / vektör kodu gibi, büyük bellek bloklarını karşılaştırarak işleyen bir program gösterin. Bu durumda, kodlayıcılar ne olduğunu
bilmese

26

Belirli CPU optimizasyonları için derleme genellikle abartılır. Sadece C ++ 'da bir program alın ve pentium PRO için optimizasyon ile derleyin ve pentium 4 üzerinde çalıştırın. Ardından pentium 4 için optimize ile yeniden derleyin. Uzun öğleden sonraları bunu birkaç programla yaparak geçirdim. Genel sonuçlar ?? Genellikle% 2-3'ten az performans artışı. Dolayısıyla teorik JIT avantajları neredeyse hiç yoktur. Performans farklılıklarının çoğu, yalnızca skaler veri işleme özellikleri kullanılırken gözlemlenebilir; bu, yine de maksimum performansa ulaşmak için nihayetinde manuel ince ayar gerektirecek bir şey. Bu tür optimizasyonların gerçekleştirilmesi yavaş ve maliyetlidir, bu da onları bazen JIT için uygunsuz hale getirir.

Gerçek dünyada ve gerçek uygulamada C ++, daha iyi önbellek performansıyla sonuçlanan daha hafif bellek alanı nedeniyle hala genellikle javadan daha hızlıdır.

Ancak tüm C ++ yeteneklerini kullanabilmeniz için geliştiricinin çok çalışması gerekir. Üstün sonuçlar elde edebilirsiniz, ancak bunun için beyninizi kullanmalısınız. C ++, size daha fazla araç sunmaya karar veren, dili iyi kullanabilmek için öğrenmeniz gereken fiyatı ödeyen bir dildir.


4
CPU optimizasyonu için derlemeniz çok fazla değil, ancak çalışma zamanı yolu optimizasyonu için derliyorsunuz. Bir yöntemin çok sık olarak belirli bir parametre ile çağrıldığını fark ederseniz, bu yordamı, devasa iş parçalarını (akışı kontrol eden bir boole durumunda) çarpanlara ayırabilecek bir sabit olarak bu parametreyle önceden derleyebilirsiniz. C ++ bu tür bir optimizasyon yapmaya yaklaşamaz.
Bill K

1
Öyleyse JIT'ler, gözlemlenen çalışma yollarından yararlanmak için rutinleri yeniden derleme konusunda nasıl çalışıyor ve bu ne kadar fark yaratıyor?
David Thornley

2
@ Bill İki şeyi karıştırıyor olabilirim ... ancak komut hattında çalışma zamanında yapılan dal tahmini, dilden bağımsız olarak benzer hedeflere ulaşmıyor mu?
Hardy

@ Zor evet, CPU dilden bağımsız olarak dal tahmini yapabilir, ancak döngünün hiçbir şey üzerinde hiçbir etkisi olmadığını gözlemleyerek tüm döngüyü çarpanlarına ayıramaz. Ayrıca, mult (0) 'ın 0 döndürmek için kablolu olduğunu ve tüm yöntem çağrısını if (param == 0) sonuç = 0 ile değiştirdiğini gözlemlemeyecektir; ve tüm işlev / yöntem çağrısından kaçının. Derleyici, neler olduğuna dair kapsamlı bir genel bakışa sahip olsaydı, C bunları yapabilirdi, ancak genellikle derleme zamanında yeterli bilgiye sahip olmazdı.
Bill K

21

JIT (Just In Time Compiling), hedef platform için optimize ettiği için inanılmaz derecede hızlı olabilir.

Bu, geliştiricinin kodu yazdığı CPU'ya bakılmaksızın, CPU'nuzun destekleyebileceği herhangi bir derleyici hilesinden yararlanabileceği anlamına gelir.

.NET JIT'in temel konsepti şu şekilde çalışır (büyük ölçüde basitleştirilmiş):

Bir yöntemi ilk kez çağırmak:

  • Program kodunuz Foo () yöntemini çağırır
  • CLR, Foo () 'yu uygulayan türe bakar ve onunla ilişkili meta verileri alır
  • Metadata'dan CLR, IL'nin (Ara bayt kodu) hangi bellek adresinde depolandığını bilir.
  • CLR, bir bellek bloğu tahsis eder ve JIT'i çağırır.
  • JIT, IL'yi yerel koda derler, tahsis edilen belleğe yerleştirir ve ardından Foo () 'nun tür meta verilerindeki işlev işaretçisini bu yerel koda işaret edecek şekilde değiştirir.
  • Yerel kod çalıştırılır.

Bir yöntemi ikinci kez çağırmak:

  • Program kodunuz Foo () yöntemini çağırır
  • CLR, Foo () uygulayan türe bakar ve meta veride işlev göstericisini bulur.
  • Bu bellek konumundaki yerel kod çalıştırılır.

Gördüğünüz gibi, 2. sefer, gerçek zamanlı optimizasyonların avantajı haricinde, neredeyse C ++ ile aynı süreçtir.

Bununla birlikte, yönetilen bir dili yavaşlatan başka genel sorunlar da vardır, ancak JIT çok yardımcı olur.


Bu arada Jonathan, sanırım birileri hala senin eşyalarını olumsuz etkiliyor. Sana oy verdiğimde bu yazıda -1 vardı.
Brian R. Bondy

12

Orion Adrian'ın cevabını beğendim ama bunun başka bir yönü var.

Aynı soru, FORTRAN gibi "insan" dillerine karşı montaj dili hakkında onlarca yıl önce sorulmuştu. Cevabın bir kısmı da benzer.

Evet, bir C ++ programı herhangi bir (önemsiz olmayan?) Algoritmada C # 'dan daha hızlı olabilir, ancak C #' daki program genellikle C ++ 'daki "naif" bir uygulamadan ve C ++' da optimize edilmiş bir sürümden daha hızlı veya daha hızlı olacaktır. geliştirilmesi daha uzun sürecektir ve yine de C # sürümünü çok küçük bir farkla geçebilir. Peki buna gerçekten değer mi?

Bu soruyu tek tek cevaplamanız gerekecek.

Bununla birlikte, uzun süredir C ++ hayranıyım ve bunun inanılmaz derecede etkileyici ve güçlü bir dil olduğunu düşünüyorum - bazen az değer verilen. Ancak birçok "gerçek hayat" probleminde (şahsen benim için bu "çözmem için para aldığım türden" anlamına gelir), C # işi daha çabuk ve daha güvenli hale getirecek.

Ödediğiniz en büyük ceza? Pek çok .NET ve Java programı hafızayı tüketir. Benzer karmaşıklığa sahip C ++ programları MB'lerin "onlarca" sını zar zor çizdiğinde .NET ve Java uygulamalarının "yüzlerce" megabayt bellek aldığını gördüm.


7

Java kodunun Hotspot ile bile C ++ 'dan daha hızlı çalışacağını ne sıklıkla bulacağınızdan emin değilim, ancak bunun nasıl olabileceğini açıklamak için biraz sallayacağım.

Derlenmiş Java kodunu JVM için yorumlanan makine dili olarak düşünün. Hotspot işlemcisi, derlenen kodun belirli parçalarının birçok kez kullanılacağını fark ettiğinde, makine kodu üzerinde bir optimizasyon gerçekleştirir. Hand-tuning Assembly, neredeyse her zaman C ++ derlenmiş koddan daha hızlı olduğundan, programlı olarak ayarlanmış makine kodunun çok da kötü olmayacağını anlamakta sorun yoktur.

Bu yüzden, oldukça tekrar eden kod için, Hotspot JVM'nin Java'yı C ++ 'dan daha hızlı çalıştırmasının mümkün olduğunu görebiliyordum ... çöp toplama devreye girene kadar. :)


İddiayı genişletebilir misin Since hand-tuning Assembly is almost always faster than C++ compiled code? "El ayarlı Assembly" ve "C ++ derlenmiş kod" ile ne demek istiyorsun?
paercebal

Bir derleyicinin optimize edicisinin kurallara uyması ve kodlayıcıların uymaması fikrine dayanır. Dolayısıyla, optimize edenin mükemmel bir şekilde optimize edemediğini anladığı kod her zaman olacaktır, oysa bir insan ya daha büyük bir resme bakarak ya da kodun gerçekte ne yaptığı hakkında daha fazla şey bilerek yapabilir. Bunun 3 yıllık bir yorum olduğunu ekleyeceğim ve HotSpot hakkında eskisinden daha çok şey biliyorum ve dinamik optimizasyonun kodu daha hızlı çalıştırmanın ÇOK güzel bir yolu olduğunu kolayca görebiliyorum.
billjamesdev

1. Hotspot veya başka herhangi bir JIT'den yapılan optimizasyonlar hala derleyici optimizasyonlarıdır. JIT, statik bir derleyiciye göre bazı sonuçları satır içi yapabilme (kod sıklıkla çağrılır) veya hatta çalıştıran işlemciye dayalı optimizasyonlar yapma avantajına sahiptir, ancak yine de bir derleyici optimizasyonudur. . . 2. Sanırım algoritma optimizasyonundan bahsediyorsunuz, "montaj ince ayarı" ndan değil. "Bir insan kodlayıcı tarafından manuel montaj ince ayarı" on yıldan fazla bir süredir derleyici optimizasyonlarından daha iyi sonuçlar üretmede başarısız oldu. Aslında, montaj ile oynayan bir insan genellikle herhangi bir optimizasyonu
mahveder

Tamam, "statik optimizasyon" yerine yanlış terminoloji, "derleyici optimizasyonu" kullandığımı anlıyorum. En azından oyun endüstrisinde, son zamanlarda PS2 için, konsolda olduğunu bildiğimiz belirli yongaları "optimize etmek" için hala elle kodlanmış montajı kullandığımızı belirtmek isterim; Bu yeni yongalar için çapraz derleyiciler henüz x86 mimarileri kadar karmaşık değil. Yukarıdaki orijinal soruya geri
dönelim

Çoğu üretim GC'sinin de elle yazılmış assembler kullandığını unutmayın, çünkü C / C ++ onu kesmez.
JD

6

Genel olarak, programınızın algoritması , uygulamanızın hızı için dilden çok daha önemli olacaktır . C ++ dahil herhangi bir dilde zayıf bir algoritma uygulayabilirsiniz. Bunu göz önünde bulundurarak, genellikle daha verimli bir algoritma uygulamanıza yardımcı olan bir dilde daha hızlı kod yazabileceksiniz.

Daha yüksek seviyeli diller, birçok verimli önceden oluşturulmuş veri yapısına daha kolay erişim sağlayarak ve verimsiz kodlardan kaçınmanıza yardımcı olacak uygulamaları teşvik ederek bu konuda çok başarılıdır. Elbette, bazen gerçekten yavaş kod yazmayı da kolaylaştırabilirler, bu nedenle hala platformunuzu bilmeniz gerekir.

Ayrıca C ++, STL kapları, otomatik işaretçiler, vb. "Yeni" (tırnak işaretlerine dikkat edin) özellikleri yakalar - örneğin, yükseltme kitaplığına bakın. Ve bazen, bazı görevleri yerine getirmenin en hızlı yolunun, daha yüksek seviyeli bir dilde yasak olan işaretçi aritmetiği gibi bir teknik gerektirdiğini fark edebilirsiniz - ancak bunlar tipik olarak, istediğiniz gibi uygulayabilen bir dilde yazılmış bir kitaplığa seslenmenize izin verir. .

Önemli olan, kullandığınız dili, ilişkili API'sini, neler yapabileceğini ve sınırlamalarının neler olduğunu bilmektir.


5

Ben de bilmiyorum ... Java programlarım her zaman yavaş. :-) Yine de, C # programlarının özellikle yavaş olduğunu hiç fark etmemiştim.


4

İşte kendi bilgisayarınızda kendi kendinize deneyebileceğiniz bir başka ilginç kriter.

ASM, VC ++, C #, Silverlight, Java applet, Javascript, Flash (AS3) ile karşılaştırır

Roozz eklenti hız demosu

Lütfen javascript hızının, onu çalıştıran tarayıcıya bağlı olarak büyük ölçüde değiştiğini unutmayın. Aynısı Flash ve Silverlight için de geçerlidir çünkü bu eklentiler barındırma tarayıcısı ile aynı süreçte çalışır. Ancak Roozz eklentisi, kendi işlemlerinde çalışan standart .exe dosyalarını çalıştırır, bu nedenle hız, barındırma tarayıcısından etkilenmez.


4

"Daha iyi performans göster" tanımlamalısınız. Biliyorum, hızı sordun ama önemli olan her şey değil.

  • Sanal makineler daha fazla çalışma zamanı ek yükü gerçekleştiriyor mu? Evet!
  • Daha fazla çalışan hafıza yiyorlar mı? Evet!
  • Daha yüksek başlangıç ​​maliyetleri var mı (çalışma zamanı başlatma ve JIT derleyicisi)? Evet!
  • Yüklü büyük bir kütüphaneye ihtiyaçları var mı? Evet!

Ve böylece, önyargılı, evet;)

C # ve Java ile aldıklarınızın bir bedelini ödersiniz (daha hızlı kodlama, otomatik bellek yönetimi, büyük kitaplık vb.). Ancak ayrıntılar hakkında pazarlık edecek fazla yeriniz yok: komple paketi alın ya da hiçbir şey.

Bu diller bazı kodları derlenmiş koddan daha hızlı çalıştırmak için optimize edebilse bile, tüm yaklaşım (IMHO) verimsizdir. Her gün bir kamyonla iş yerinize 5 mil gidip geldiğinizi hayal edin! Rahattır, iyi hissettirir, güvendesiniz (aşırı çökme bölgesi) ve bir süre gaza bastıktan sonra, standart bir araba kadar hızlı bile olacak! Neden hepimizin işe gidecek bir kamyonu yok? ;)

C ++ 'da ödediğinizin karşılığını alırsınız, daha fazla değil, daha az değil.

Bjarne Stroustrup'tan alıntı: "C ++, çok az çöp ürettiği için en sevdiğim çöp toplama dilidir" bağlantı metni


Eh, sakıncaları hakkında iyi bir fikri olduğunu düşünüyorum, ayrıca şöyle dedi: "C kendini ayağından vurmayı kolaylaştırır; C ++ bunu zorlaştırır, ama yaptığında tüm bacağını uçurur";)
Frunsi

"Yüklü bir kitaplık gerektiriyorlar mı?"
toc777

"C ++ 'da ödediğinizin karşılığını alırsınız, daha fazla değil, daha az değil. Sayaç örneği: OCaml ve C ++ 'da (GNU GCC), mevcut kümeyi yeniden kullanmak için eklenen bir öğe zaten mevcutsa, özyinelemeden uzun süre dışarı çıkmak için bir istisna kullanan bir RB ağaç uygulamasını karşılaştırdım. OCaml, C ++ 'dan 6 kat daha hızlıydı çünkü yığın çözüldüğünde yıkıcıları kontrol etmek için para ödemiyor.
JD

3
@Jon: ama zamanın bir noktasında (daha sonra?) Yine de nesneleri yok etmesi gerekiyor (en azından hafızasını serbest bırakması gerekiyor). Ayrıca, istisnaların istisnai durumlar için olduğunu, en azından C ++ 'da bu kurala uyulması gerektiğini unutmayın. C ++ istisnaları, istisnalar oluştuğunda ağır olabilir, bu bir değiş tokuştur.
Frunsi

@Jon: Belki kıyaslamanı timesbir kabukta tekrar etmeyi dene . Böylece sadece tek bir yönü değil, tüm programı kontrol eder. Sonuçlar benzer mi peki?
Frunsi

3

Bir Java veya C # derleyicisinden üretilen çalıştırılabilir kod yorumlanmaz - "tam zamanında" (JIT) yerel koda derlenir. Bu nedenle, bir Java / C # programında ilk kez kod çalıştırma sırasında karşılaşıldığında, "çalışma zamanı derleyicisi" (diğer adıyla JIT derleyicisi) bayt kodunu (Java) veya IL kodunu (C #) yerel makine talimatlarına dönüştürdüğü için bazı ek yükler vardır. Bununla birlikte, uygulama çalışırken bu kodla bir sonraki sefer karşılaşıldığında, yerel kod hemen yürütülür. Bu, bazı Java / C # programlarının başlangıçta nasıl yavaş göründüğünü, ancak daha uzun süre çalıştıkça daha iyi performans gösterdiğini açıklar. İyi bir örnek, ASP.Net web sitesidir. Web sitesine ilk erişildiğinde, C # kodu JIT derleyicisi tarafından yerel koda derlendiğinden biraz daha yavaş olabilir.


3

Sorduğunuz belirli soru hakkında burada bazı iyi yanıtlar. Geri çekilip büyük resme bakmak istiyorum.

Kullanıcınızın yazdığınız yazılımın hızı hakkındaki algısının, kodcunun ne kadar iyi optimize ettiğinden başka birçok faktörden etkilendiğini unutmayın. İşte bazı örnekler:

  • Manuel bellek yönetiminin doğru bir şekilde yapılması (sızıntı olmaması) ve verimli bir şekilde yapılması daha da zordur (işiniz bittikten hemen sonra boş bellek). Bir GC kullanmak, genel olarak, belleği iyi yöneten bir program üretme olasılığı daha yüksektir. GC'yi aşmak için çok çalışmaya ve yazılımınızı teslim etmeyi ertelemeye istekli misiniz?

  • C # kodumun okunması ve anlaşılması C ++ 'dan daha kolaydır. Ayrıca kendimi C # kodumun doğru çalıştığına ikna etmek için daha fazla yolum var. Bu, algoritmalarımı daha az hata oluşturma riski ile optimize edebileceğim anlamına gelir (ve kullanıcılar, hızlı bir şekilde yapsa bile, çöken yazılımları sevmezler!)

  • Yazılımımı C # ile C ++ 'dan daha hızlı oluşturabilirim. Bu, performans üzerinde çalışmak için zaman kazandırır ve yine de yazılımımı zamanında teslim eder.

  • C # ile iyi bir UI yazmak C ++ 'dan daha kolaydır, bu nedenle UI yanıt verirken çalışmayı arka plana itme veya programın bir süre engellenmesi gerektiğinde ilerleme veya Hearbeat UI sağlama olasılığım daha yüksektir. Bu hiçbir şeyi hızlandırmaz, ancak kullanıcıları bekleme konusunda daha mutlu eder.

C # hakkında söylediğim her şey muhtemelen Java için doğrudur, sadece kesin olarak söyleyecek deneyime sahip değilim.


3

C ++ öğrenen bir Java / C # programcısıysanız, Java / C # açısından düşünmeye devam etmek ve kelimesi kelimesine C ++ sözdizimine çevirmek cazip gelecektir. Bu durumda, yorumlanan / JIT yerine yerel kodun yalnızca daha önce bahsedilen avantajlarını elde edersiniz. C ++ ile Java / C # arasında en büyük performans kazancını elde etmek için, C ++ 'da düşünmeyi öğrenmeli ve özellikle C ++' nın güçlü yönlerinden yararlanmak için kod tasarlamalısınız.

Edsger Dijkstra'dan söz etmek gerekirse : [ilk diliniz] zihni iyileşmenin ötesinde sakat bırakıyor. Jeff Atwood'dan
başka sözlerle : [ana dilinizi] herhangi bir yeni dilde yazabilirsiniz.


1
"FORTRAN'ı herhangi bir dilde yazabilirsin" sözünün Jeff'in kariyerinden önce geldiğinden şüpheleniyorum.
David Thornley

3

En önemli JIT optimizasyonlarından biri yöntem satır içi işlemidir. Java, çalışma zamanı doğruluğunu garanti edebiliyorsa, sanal yöntemleri bile satır içi yapabilir. Bu tür bir optimizasyon genellikle standart statik derleyiciler tarafından gerçekleştirilemez çünkü tam program analizine ihtiyaç duyar, bu da ayrı derlemeden dolayı zordur (aksine, JIT tüm programa sahiptir). Yöntem satır içi, diğer optimizasyonları iyileştirerek optimize etmek için daha büyük kod blokları sağlar.

Java / C # 'da standart bellek tahsisi de daha hızlıdır ve serbest bırakma (GC) çok daha yavaş değil, yalnızca daha az belirleyicidir.


Not olduğu freeve deletedeterministik ya ve GC yerleştirmeden değil deterministik yapılabilir değildir.
JD

3

Sanal makine dillerinin derlenmiş dillerden daha iyi performans gösterme olasılığı düşüktür, ancak (en azından) aşağıdaki nedenlerden dolayı önemli olmayacak kadar yaklaşabilirler (burada Java için konuşuyorum çünkü hiç C # yapmadım).

1 / Java Runtime Environment, genellikle sık çalıştırılan kod parçalarını algılayabilir ve bu bölümlerin tam zamanında (JIT) derlenmesini gerçekleştirebilir, böylece gelecekte tam derlenmiş hızda çalışırlar.

2 / Java kitaplıklarının geniş bölümleri, bir kitaplık işlevini çağırdığınızda yorumlanmayan, derlenmiş kodu çalıştıracağınız şekilde derlenir. OpenJDK'yi indirerek kodu (C cinsinden) görebilirsiniz.

3 / Çok büyük hesaplamalar yapmadığınız sürece, programınız çoğu zaman çalışıyorken, çok yavaş (nispeten konuşan) bir insandan girdi bekler.

4 / Java bayt kodunun çoğu, sınıf yüklenirken yapıldığından, normal çalışma zamanı kontrolleri ek yükü büyük ölçüde azalır.

5 / En kötü durumda, performans yoğun kod derlenmiş bir modüle çıkarılabilir ve tam hızda çalışması için Java'dan çağrılabilir (bkz. JNI).

Özetle, Java bayt kodu hiçbir zaman yerel makine dilinden daha iyi performans göstermez, ancak bunu azaltmanın yolları vardır. Java'nın en büyük avantajı (gördüğüm kadarıyla) BÜYÜK standart kitaplık ve çapraz platform doğasıdır.


1
Madde 2, "Java kitaplıklarının geniş bölümleri, bir kitaplık işlevini çağırdığınızda yorumlanmayan, derlenmiş kodu çalıştıracağınız şekilde derlenir": Bunun için bir alıntı var mı? Eğer gerçekten tarif ettiğiniz gibi olsaydı, hata ayıklayıcımdan yerel koda sık sık girmeyi beklerdim, ama yapmıyorum.
cero

Re: cero Debugger'lar genellikle daha az verimli ancak daha etkileyici yollar kullanır ve bu nedenle performansla ilgili herhangi bir şey için iyi bir işaret değildir.
Guvante

2
Bu HUGH kitaplığı için başka bir büyük performans kazancı daha var - kitaplık kodu muhtemelen birçok programcının kendi başına yazacağından daha iyi yazılmıştır (sınırlı bir süre ve uzmanlık bilgisinin olmaması nedeniyle) ve birçok nedenden dolayı, programcılar genellikle kütüphane.
Liran Orevi

3

Orion Adrian , görüşlerinizin ne kadar temelsiz olduğunu görmek için gönderinizi tersine çevirmeme izin verin, çünkü C ++ hakkında da çok şey söylenebilir. Ve Java / C # derleyicisinin boş işlevleri optimize ettiğini söylemek, gerçekten optimizasyon konusunda uzmanım değilmişsiniz gibi görünmenizi sağlar, çünkü a) gerçek bir program neden gerçekten kötü eski kod haricinde boş işlevler içermelidir, b) bu ​​gerçekten değildir siyah ve kanayan kenar optimizasyonu.

Bu cümlenin dışında, pervasızca işaretçiler hakkında konuştunuz, ancak Java ve C #'daki nesneler temelde C ++ işaretçileri gibi çalışmıyor mu? Çakışmasınlar mı? Boş olamazlar mı? C (ve çoğu C ++ uygulaması) restrict anahtar kelimesine sahiptir, her ikisinin de değer türleri vardır, C ++, boş olmayan garantiyle değere başvuruya sahiptir. Java ve C # ne sunar?

>>>>>>>>>>

Genel olarak, C ve C ++ aynı derecede hızlı veya daha hızlı olabilir, çünkü AOT derleyicisi - kodunuzu dağıtımdan önce, bir kez ve herkes için, yüksek belleğinizdeki birçok çekirdek derleme sunucunuzda derleyen bir derleyici - bir C # derlenmiş programın optimizasyonlarını yapabilir yapamaz çünkü bunu yapmak için tonla zamanı vardır. Derleyici, makinenin Intel mi yoksa AMD mi olduğunu belirleyebilir; Pentium 4, Core Solo veya Core Duo; veya SSE4, vb. destekliyorsa ve derleyiciniz çalışma zamanı gönderimini desteklemiyorsa, bir avuç özelleştirilmiş ikili dosya dağıtarak bunu kendiniz çözebilirsiniz.

AC # programı yaygın olarak tüm makinelerde de adam gibi çalışır, ancak tek bir konfigürasyonda (yani işlemci, komut kümesi, diğer donanım) için olabilir olduğunca optimize edilmediğini böylece onu çalıştıran üzerine derlenmektedir ve gereken biraz zaman harcamak ilk. Döngü fisyonu, döngü ters çevirme, otomatik vektörleştirme, tüm program optimizasyonu, şablon genişletme, IPO ve daha pek çok özellik, son kullanıcıyı rahatsız etmeyecek şekilde tamamen ve tamamen çözülmesi çok zordur.

Ek olarak, belirli dil özellikleri, C ++ veya C'deki derleyicinin kodunuz hakkında, Java / C # derleyicisinin yapması güvenli olmayan belirli bölümleri optimize etmesine izin veren varsayımlarda bulunmasına olanak tanır. Tam türdeki jenerik kimliğine veya garantili bir program akışına erişiminiz olmadığında, güvenli olmayan birçok optimizasyon vardır.

Ayrıca C ++ ve C, tek bir yazmaç artışıyla birçok yığın tahsisatını aynı anda yapar; bu, çöp toplayıcı ile kodunuz arasındaki soyutlama katmanı için kesinlikle Javas ve C # tahsislerinden daha verimlidir.

Şimdi bir sonraki noktada Java için konuşamam, ancak C ++ derleyicilerinin, yöntemin gövdesinin boş olduğunu bildiğinde aslında yöntemleri ve yöntem çağrılarını kaldıracağını biliyorum, yaygın alt ifadeleri ortadan kaldırır, deneyebilir ve yeniden deneyebilir Optimal yazmaç kullanımını bulmak için, sınır kontrolünü zorlamaz, döngüleri ve iç döngüleri otomatik olarak düzenler ve içten dışa çevirir, koşulluları döngülerin dışına taşır, döngüleri böler ve ayırır. Std :: vector'u, C yöntemini yaptığınız gibi yerel sıfır genel gider dizilerine genişletir. Prosedürler arası optimizasyonlar yapacak. Doğrudan arayan sitede dönüş değerleri oluşturacaktır. İfadeleri katlayacak ve yayacaktır. Verileri önbellek dostu bir şekilde yeniden düzenleyecektir. İp atlama yapacak. Sıfır çalışma zamanı ek yükü ile derleme süresi ışın izleyicileri yazmanıza olanak tanır. Çok pahalı grafik tabanlı optimizasyonlar yapacak. Belirli kodları sözdizimsel olarak tamamen eşit olmayan ancak semantik olarak eşdeğer kodlarla değiştirirse gücü azaltacaktır (eski "xor foo, foo" bu türden en basit, ancak modası geçmiş optimizasyondur). Nazikçe sorarsanız, IEEE kayan nokta standartlarını atlayabilir ve kayan noktalı işlenen yeniden sıralama gibi daha fazla optimizasyonu etkinleştirebilirsiniz. Kodunuza masaj yaptıktan ve katlettikten sonra, tüm süreci tekrarlayabilir, çünkü çoğu zaman, belirli optimizasyonlar daha da kesin optimizasyonların temelini oluşturur. Ayrıca, karıştırılmış parametrelerle yeniden deneyebilir ve diğer varyantın kendi dahili sıralamasında nasıl puan aldığını görebilir. Ve bu tür bir mantığı kodunuzun tamamında kullanacaktır. belirli kodları sözdizimsel olarak tamamen eşit olmayan ancak anlamsal olarak eşdeğer kodla değiştirdi mi (eski "xor foo, foo" bu türden modası geçmiş olsa da en basit olanıdır). Nazikçe sorarsanız, IEEE kayan nokta standartlarını atlayabilir ve kayan noktalı işlenen yeniden sıralama gibi daha fazla optimizasyonu etkinleştirebilirsiniz. Kodunuza masaj yaptıktan ve katlettikten sonra, tüm süreci tekrarlayabilir, çünkü çoğu zaman, belirli optimizasyonlar daha da kesin optimizasyonların temelini oluşturur. Ayrıca, karıştırılmış parametrelerle yeniden deneyebilir ve diğer varyantın kendi dahili sıralamasında nasıl puan aldığını görebilir. Ve bu tür bir mantığı kodunuzun tamamında kullanacaktır. belirli kodları sözdizimsel olarak tamamen eşit olmayan ancak anlamsal olarak eşdeğer kodla değiştirdi mi (eski "xor foo, foo" bu türden modası geçmiş olsa da en basit olanıdır). Nazikçe sorarsanız, IEEE kayan nokta standartlarını atlayabilir ve kayan noktalı işlenen yeniden sıralama gibi daha fazla optimizasyonu etkinleştirebilirsiniz. Kodunuza masaj yaptıktan ve katlettikten sonra, tüm süreci tekrarlayabilir, çünkü çoğu zaman, belirli optimizasyonlar daha da kesin optimizasyonların temelini oluşturur. Ayrıca, karıştırılmış parametrelerle yeniden deneyebilir ve diğer varyantın kendi dahili sıralamasında nasıl puan aldığını görebilir. Ve bu tür bir mantığı kodunuzun tamamında kullanacaktır. Nazikçe sorarsanız, IEEE kayan nokta standartlarını atlayabilir ve kayan noktalı işlenen yeniden sıralama gibi daha fazla optimizasyonu etkinleştirebilirsiniz. Kodunuza masaj yaptıktan ve katlettikten sonra, tüm süreci tekrarlayabilir, çünkü çoğu zaman, belirli optimizasyonlar daha da kesin optimizasyonların temelini oluşturur. Ayrıca, karıştırılmış parametrelerle yeniden deneyebilir ve diğer varyantın kendi dahili sıralamasında nasıl puan aldığını görebilir. Ve bu tür bir mantığı kodunuzun tamamında kullanacaktır. Nazikçe sorarsanız, IEEE kayan nokta standartlarını atlayabilir ve kayan noktalı işlenen yeniden sıralama gibi daha fazla optimizasyonu etkinleştirebilirsiniz. Kodunuza masaj yaptıktan ve katlettikten sonra, tüm süreci tekrarlayabilir, çünkü çoğu zaman, belirli optimizasyonlar daha da kesin optimizasyonların temelini oluşturur. Ayrıca, karıştırılmış parametrelerle yeniden deneyebilir ve diğer varyantın kendi dahili sıralamasında nasıl puan aldığını görebilir. Ve bu tür bir mantığı kodunuzun tamamında kullanacaktır. Ayrıca, karıştırılmış parametrelerle yeniden deneyebilir ve diğer varyantın kendi dahili sıralamasında nasıl puan aldığını görebilir. Ve bu tür bir mantığı kodunuzun tamamında kullanacaktır. Ayrıca, karıştırılmış parametrelerle yeniden deneyebilir ve diğer varyantın kendi dahili sıralamasında nasıl puan aldığını görebilir. Ve bu tür bir mantığı kodunuzun tamamında kullanacaktır.

Gördüğünüz gibi, belirli C ++ veya C uygulamalarının daha hızlı olmasının birçok nedeni vardır.

Şimdi tüm bunların söylendiği gibi, C ++ 'da C # ile yapabileceğiniz her şeyi, özellikle de sayı hesaplama, gerçek zamanlı ve metale yakın alemde, ancak yalnızca orada değil, ortadan kaldıracak birçok optimizasyon yapılabilir. Uzun bir yol kat etmek için tek bir işaretçiye dokunmanıza bile gerek yok.

Yani ne yazdığına bağlı olarak, birini veya diğerini seçerim. Ancak donanıma bağlı olmayan bir şey yazıyorsanız (sürücü, video oyunu, vb.), C # 'ın performansı hakkında endişelenmem (yine Java hakkında konuşamam). İyi olacak.

<<<<<<<<<<

Genel olarak, belirli genelleştirilmiş argümanlar belirli gönderilerde kulağa havalı gelebilir, ancak genel olarak kesinlikle inandırıcı gelmez.

Her neyse, barış yapmak için: AOT , JIT gibi harika . Tek doğru cevap şu olabilir: Duruma göre değişir. Ve gerçek zeki insanlar her iki dünyanın da en iyisini kullanabileceğinizi bilirler.


2

Yalnızca Java yorumlayıcısı, derleyicinizin yazdığınız C ++ kodu için ürettiği makine kodundan daha iyi optimize edilmiş makine kodu üretiyorsa , C ++ kodunun Java'dan ve yorumlama maliyetinden daha yavaş olduğu noktaya kadar gerçekleşir.

Bununla birlikte, bunun gerçekleşme olasılığı oldukça düşüktür - belki Java'nın çok iyi yazılmış bir kitaplığı yoksa ve kendi kötü yazılmış C ++ kitaplığınız yoksa.


Ayrıca belirli bir dil ağırlığı olduğuna da inanıyorum, daha düşük seviyede, daha az soyutlama ile çalışırken daha hızlı bir program geliştiriyor olacaksınız. Bu, bayt kodu yürütmenin kendisiyle ilgili noktalar ile ilgisizdir.
Brian R. Bondy

2

Aslında, C # Java gibi sanal bir makinede çalışmaz. IL, tamamen yerel kod olan ve yerel kodla aynı hızda çalışan birleştirme dili olarak derlenir. JIT maliyetini tamamen ortadan kaldıran bir .NET uygulamasına önceden JIT uygulayabilir ve ardından tamamen yerel kodu çalıştırırsınız.

NET'teki yavaşlama, .NET kodunun daha yavaş olması nedeniyle değil, çöp toplama, referansları kontrol etme, tam yığın çerçevelerini saklama gibi şeyleri arka planda daha çok yaptığı için olacaktır. Bu, ne zaman oldukça güçlü ve yararlı olabilir? bina uygulamaları, ancak aynı zamanda bir bedeli vardır. Tüm bunları bir C ++ programında da yapabileceğinizi unutmayın (çekirdek .NET işlevlerinin çoğu aslında ROTOR'da görüntüleyebileceğiniz .NET kodudur). Bununla birlikte, aynı işlevselliği elle yazarsanız, .NET çalışma zamanı optimize edildiğinden ve hassas bir şekilde ayarlandığından, muhtemelen çok daha yavaş bir programla sonuçlanırsınız.

Bununla birlikte, yönetilen kodun güçlü yönlerinden biri, tamamen doğrulanabilir olmasıdır, yani. Kodun başka bir işlemin belleğine asla erişmeyeceğini veya siz onu çalıştırmadan önce kötü şeyler yapmayacağını doğrulayabilirsiniz. Microsoft, şaşırtıcı bir şekilde% 100 yönetilen bir ortamın, yönetilen programlar tarafından artık ihtiyaç duyulmayan güvenlik özelliklerini kapatmak için bu doğrulamadan yararlanarak herhangi bir modern işletim sisteminden çok daha hızlı performans gösterebileceğini şaşırtıcı bir şekilde gösteren bir tam olarak yönetilen işletim sistemi araştırma prototipine sahiptir. (bazı durumlarda 10x gibi konuşuyoruz). SE radyoda bu projeden bahseden harika bir bölüm var.


1

Bazı durumlarda, yönetilen kod aslında yerel koddan daha hızlı olabilir . Örneğin, "işaretle ve süpür" çöp toplama algoritmaları, JRE veya CLR gibi ortamların çok sayıda kısa ömürlü (genellikle) nesneyi tek bir geçişte serbest bırakmasına izin verir, burada çoğu C / C ++ yığın nesnesi bir kerede serbest bırakılır. bir zaman.

Gönderen wikipedia :

Pek çok pratik amaç için, çöp toplama dillerinde uygulanan yoğun ayırma / ayırma yoğun algoritmalar, aslında manuel yığın tahsisi kullanan eşdeğerlerinden daha hızlı olabilir. Bunun ana nedenlerinden biri, çöp toplayıcının, çalışma zamanı sisteminin tahsis etme ve ayırma işlemlerini potansiyel olarak avantajlı bir şekilde amorti etmesine izin vermesidir.

Bununla birlikte, çok fazla C # ve çok fazla C ++ yazdım ve çok sayıda kıyaslama yaptım. Deneyimlerime göre, C ++, C # 'dan iki şekilde çok daha hızlıdır: (1) C # ile yazdığınız bir kodu alırsanız, onu C ++' ya taşıyın, yerel kod daha hızlı olma eğilimindedir . Ne kadar hızlı? Pekala, çok değişiklik gösterir, ancak% 100 hız artışı görmek nadir değildir. (2) Bazı durumlarda, çöp toplama, yönetilen bir uygulamayı büyük ölçüde yavaşlatabilir. .NET CLR, büyük yığınlarla (örneğin,> 2GB) korkunç bir iş çıkarır ve sonuçta, ara ömrü olan çok az nesneye sahip olan veya hiç olmayan uygulamalarda bile, GC'de çok fazla zaman harcayabilir.

Elbette, karşılaştığım çoğu durumda, yönetilen diller yeterince hızlı, uzun bir atışla ve C ++ 'ın ekstra performansı için bakım ve kodlama ödünleşimi kesinlikle iyi bir şey değil.


1
Sorun şu ki, bir web sunucusu gibi uzun süre çalışan işlemler için, belleğiniz zamanla o kadar parçalanmış hale gelir ki (bir C ++ yazılı programda), çöp toplamaya benzeyen bir şey uygulamanız (veya sık sık yeniden başlatmanız gerekir, bkz. IIS ).
Tony BenBrahim

3
Sonsuza kadar çalışması gereken büyük Unix programlarında bunu gözlemlemedim. Bellek yönetimi için C ++ 'dan daha kötü olan C ile yazılma eğilimindedirler.
David Thornley

Tabii ki soru, bir programın yönetilen kod ile yönetilmeyen koddaki bir uygulamasını mı yoksa dilin teorik olarak en yüksek performansını mı karşılaştırdığımızdır. Açıktır ki, yönetilmeyen kod her zaman en az yönetilen kadar hızlı olabilir, en kötü durumda yönetilen kodla tam olarak aynı şeyi yapan yönetilmeyen bir program yazabilirsiniz! Ancak çoğu performans sorunu mikro değil, algoritmiktir. Ayrıca, yönetilen ve yönetilmeyen kodu aynı şekilde optimize edemezsiniz, bu nedenle "C # 'da C ++" genellikle iyi çalışmayacaktır.
kyoryu

2
C / C ++ 'da kısa ömürlü nesneleri yığın üzerinde tahsis edebilirsiniz ve uygun olduğunda yaparsınız. Yönetilen kodda yapamazsınız , seçeneğiniz yoktur. Ayrıca, C / C ++ sen yapabilirsiniz Bitişik alanlardaki nesnelerin listeleri tahsis (yeni Foo [100]), yapamazsınız yönetilen kod. Yani karşılaştırmanız geçerli değil. Eh, bu seçim gücü geliştiricilere bir yük bindirir, ancak bu şekilde yaşadıkları dünyayı tanımayı öğrenirler (hafıza ......).
Frunsi

@frunsi: "C / C ++ 'da bitişik alanlardaki nesne listelerini (yeni Foo [100]) tahsis edebilirsiniz, yönetilen kodda yapamazsınız". Bu yanlış. Yerel değer türleri yığın olarak ayrılır ve hatta C # 'da bunların ayırma dizilerini yığınlayabilirsiniz. Kararlı durumda tamamen tahsissiz olan C # ile yazılmış üretim sistemleri bile vardır.
JD


1

Aslında Sun'ın HotSpot JVM'si "karışık mod" yürütmeyi kullanır. Yöntemin bayt kodunu, belirli bir kod bloğunun (yöntem, döngü, try-catch bloğu, vb.) Çok çalıştırılacağını belirleyene kadar (genellikle bir tür sayaç aracılığıyla) yorumlar ve ardından JIT onu derler. JIT'in bir yöntemi derlemesi için gereken süre, nadiren çalıştırılan bir yöntemse, yöntemin yorumlanması gerektiğinden genellikle daha uzun sürer. "Karma mod" için performans genellikle daha yüksektir çünkü JVM, nadiren çalıştırılan JIT koduyla zaman kaybetmez. C # ve .NET bunu yapmaz. .NET JIT, çoğu zaman zaman kaybına neden olan her şeyi kullanır.


1

PA-8000'de çalışan ve genellikle programları yerel olarak olduğundan daha hızlı çalıştıran bir PA-8000 tercümanı olan HP Labs ' Dynamo hakkında okuyun . O zaman hiç de şaşırtıcı görünmeyecek!

Bunu bir "ara adım" olarak düşünmeyin - bir programı çalıştırmak herhangi bir dilde birçok başka adımı içerir.

Genellikle şu noktaya gelir:

  • programların etkin noktaları vardır, bu nedenle, çalıştırmanız gereken kodun% 95'ini daha yavaş çalıştırsanız bile,% 5 oranında daha hızlıysanız, yine de performans açısından rekabetçi olabilirsiniz.

  • Bir HLL, amacınız hakkında C / C ++ gibi bir LLL'den daha fazlasını bilir ve bu nedenle daha optimize edilmiş kod üretebilir (OCaml'de daha fazlası vardır ve pratikte genellikle daha hızlıdır)

  • Bir JIT derleyicisi, statik bir derleyicinin sahip olmadığı pek çok bilgiye sahiptir (bu sefer sahip olduğunuz gerçek veriler gibi)

  • Bir JIT derleyicisi, geleneksel bağlayıcıların gerçekten yapmasına izin verilmeyen optimizasyonları çalışma zamanında yapabilir (ortak durum düz olacak şekilde dalları yeniden düzenlemek veya kitaplık çağrılarını sıralamak gibi)

Sonuç olarak, C / C ++ performans açısından oldukça kötü dillerdir: veri türleriniz hakkında nispeten az bilgi vardır, verileriniz hakkında bilgi yoktur ve çalışma zamanı optimizasyonuna izin verecek dinamik çalışma süresi yoktur.


1

Java veya CLR C ++ 'dan daha hızlı olduğunda kısa patlamalar yaşayabilirsiniz, ancak genel olarak performans uygulamanın ömrü boyunca daha kötüdür: bununla ilgili bazı sonuçlar için www.codeproject.com/KB/dotnet/RuntimePerformance.aspx adresine bakın.



1

Anladığım kadarıyla, C / C ++ belirli bir makine mimarisinde çalışmak için yerel kod üretir. Tersine, Java ve C # gibi diller, yerel mimariyi soyutlayan bir sanal makinenin üzerinde çalışır. Mantıksal olarak, Java veya C # için bu ara adımdan dolayı C ++ hızına uyması imkansız görünebilir, ancak bana en son derleyicilerin ("sıcak nokta") bu hıza ulaşabileceği veya hatta onu aşabileceği söylendi.

Bu mantıksız. Bir ara temsilin kullanılması, doğal olarak performansı düşürmez. Örneğin, llvm-gcc, LLVM IR (sanal sonsuz kayıt makinesi) aracılığıyla C ve C ++ 'yı yerel koda derler ve mükemmel performansa ulaşır (genellikle GCC'yi yener).

Belki de bu bir dil sorusundan çok bir derleyici sorusudur, ancak herhangi biri bu sanal makine dillerinden birinin ana dilden daha iyi performans göstermesinin nasıl mümkün olduğunu sade bir İngilizce ile açıklayabilir mi?

İşte bazı örnekler:

  • JIT derlemesine sahip sanal makineler, çalışma zamanı kod üretimini kolaylaştırır (örn System.Reflection.Emit. .NET üzerinde), böylece üretilen kodu anında C # ve F # gibi dillerde derleyebilirsiniz, ancak C veya C ++ dillerinde nispeten yavaş bir yorumlayıcı yazmaya başvurmanız gerekir. Örneğin, normal ifadeler uygulamak için.

  • Sanal makinenin parçaları (örneğin yazma engeli ve ayırıcı) genellikle elle kodlanmış assembler'da yazılır çünkü C ve C ++ yeterince hızlı kod üretmez. Bir program, bir sistemin bu parçalarına vurgu yaparsa, o zaman C veya C ++ ile yazılabilen her şeyden daha iyi performans gösterebilir.

  • Yerel kodun dinamik olarak bağlanması, performansı engelleyebilen ve tüm program optimizasyonunu ortadan kaldıran bir ABI'ye uyum gerektirirken, bağlama genellikle VM'lerde ertelenir ve tüm program optimizasyonlarından (.NET'in yeniden oluşturulmuş jenerikleri gibi) yararlanabilir.

Ayrıca, üretken olmayan bir şekilde kutuplaştırılmış bir bakış açısı sunan paercebal'in yukarıdaki yüksek oylu cevabıyla ilgili bazı sorunları da ele almak istiyorum (çünkü birisi cevabı hakkındaki yorumlarımı silmeye devam ediyor):

Kod işleme derleme zamanında yapılacaktır ...

Bu nedenle, şablon metaprogramlama yalnızca program derleme zamanında mevcutsa çalışır ki bu genellikle böyle değildir, örneğin, C ++ ile rekabet gücü yüksek bir düzenli ifade kitaplığı yazmak imkansızdır, çünkü çalışma zamanı kod üretme yeteneğinden yoksundur (önemli bir yönü) metaprogramming).

... türlerle oynamak derleme zamanında yapılır ... Java veya C # eşdeğeri yazmak için en iyi durumda zahmetlidir ve türler derleme zamanında bilinse bile çalışma zamanında her zaman daha yavaş ve çözülür.

C # 'da, bu yalnızca başvuru türleri için geçerlidir ve değer türleri için doğru değildir.

JIT optimizasyonu ne olursa olsun, hiçbir şey belleğe doğrudan işaretçi erişimi kadar hızlı gidemez ... Eğer bellekte bitişik veriye sahipseniz, C ++ işaretçileriyle (yani C işaretçileri ... Sezar'a hakkını verelim) çok daha hızlı gidecektir. Java / C # 'dan daha fazla.

İnsanlar SciMark2 kıyaslamasından SOR testinde Java'nın C ++ 'yı geçtiğini gözlemlediler çünkü işaretçiler örtüşme ile ilgili optimizasyonları .

Ayrıca .NET'in bağlamadan sonra dinamik olarak bağlantılı kitaplıklar arasında jeneriklerin tür uzmanlaşması yaptığını, ancak şablonların bağlanmadan önce çözülmesi gerektiğinden C ++ 'ın bunu yapamayacağını belirtmek gerekir. Ve tabii ki jeneriklerin şablonlara göre en büyük avantajı anlaşılır hata mesajları.


0

Bazılarının söylediklerine ek olarak, benim anlayışıma göre .NET ve Java bellek ayırmada daha iyidir. Örneğin, parçalanmış haldeyken belleği sıkıştırırken C ++ bunu yapamaz (doğal olarak, ancak akıllı bir çöp toplayıcı kullanıyorsanız, yapabilir).


Veya daha iyi bir C ++ ayırıcısı ve / veya nesne havuzu kullanıyorsanız. Bu, C ++ bakış açısından sihirden uzaktır ve "yığın tahsisi" nin hızlı bir yığın tahsisi haline gelmesi için kısalabilir.
paercebal

Her zaman her şeyi öbeğe ayırırsanız, o zaman .NET ve Java C / C ++ 'dan daha iyi performans gösterebilir. Ama bunu C / C ++ 'da yapmayacaksınız.
Frunsi

0

Çok fazla hıza ihtiyaç duyan herhangi bir şey için, JVM sadece bir C ++ uygulaması çağırır, bu nedenle bu, JVM'nin çoğu işletim sistemi ile ilgili şeyler için ne kadar iyi olduğundan çok, kütüphanelerinin ne kadar iyi olduğu sorusudur. Çöp toplama hafızanızı yarıya indirir, ancak daha meraklı STL ve Boost özelliklerinden bazılarını kullanmak aynı etkiye sahip olacak, ancak çoğu kez hata potansiyeli ile.

Sadece C ++ kitaplıklarını ve yüksek seviyeli özelliklerini birçok sınıf içeren büyük bir projede kullanıyorsanız, muhtemelen bir JVM kullanmaktan daha yavaş çalışacaksınız. Çok daha fazla hata eğilimi dışında.

Bununla birlikte, C ++ 'nın faydası, kendinizi optimize etmenize izin vermesidir, aksi takdirde derleyicinin / jvm'nin yaptıklarına bağlı kalırsınız. Kendi kapsayıcılarınızı oluşturursanız, hizalanmış kendi bellek yönetiminizi yazın, SIMD kullanın ve burada ve oraya montaja bırakın, çoğu C ++ derleyicisinin kendi başına yapacağına göre en az 2x-4x kat hızlandırabilirsiniz. Bazı işlemler için 16x-32x. Bu, aynı algoritmaları kullanır, daha iyi algoritmalar kullanır ve paralelleştirirseniz, artışlar dramatik olabilir, bazen yaygın olarak kullanılan yöntemlerden binlerce kat daha hızlı olabilir.


0

Birkaç farklı noktadan bakıyorum.

  1. Sonsuz zaman ve kaynaklar verildiğinde, yönetilen veya yönetilmeyen kod daha hızlı olacak mı? Açıkçası, cevap, yönetilmeyen kodun her zaman en azından bu açıdan yönetilen kodu bağlayabileceğidir - en kötü durumda olduğu gibi, yönetilen kod çözümünü sadece sabit kodlamanız gerekir.
  2. Bir programı bir dilde alıp doğrudan diğerine çevirirseniz, ne kadar kötü performans gösterir? Muhtemelen herhangi iki dil için çok fazla . Çoğu dil farklı optimizasyonlar gerektirir ve farklı sorunlara sahiptir. Mikro performans genellikle bu ayrıntıları bilmekle ilgilidir.
  3. Sınırlı zaman ve kaynaklar verildiğinde, iki dilden hangisi daha iyi bir sonuç verecektir? Bu en ilginç sorudur, çünkü yönetilen bir dil biraz daha yavaş kod üretebilirken (o dil için makul şekilde yazılmış bir program verildiğinde), bu sürüm muhtemelen daha erken tamamlanacak ve optimizasyona daha fazla zaman harcanmasına izin verecektir.

0

Çok kısa bir cevap: Sabit bir bütçe verildiğinde, bir C ++ uygulamasından daha iyi performans gösteren java uygulaması elde edeceksiniz (ROI ile ilgili hususlar) Ek olarak, Java platformu, etkin noktalarınızı daha hızlı belirlemenize yardımcı olacak daha iyi profil oluşturuculara sahiptir.

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.