Yalnızca başlık kitaplıkları daha mı verimli?


48

Varsayımlar

  1. Yalnızca üstbilgi kitaplıkların C ++ için avantajlarından biri, ayrı olarak derlenmelerine gerek olmamasıdır.

  2. C ve C ++ ' inlineda işlev yalnızca bir başlık dosyasında tanımlanmışsa anlamlıdır *.

  3. Geleneksel olarak, C, .c / .h düzeni kullanılmıştır, burada başlığın çeviri biriminin asgari ortak arayüzünü temsil ettiği görülmektedir. Benzer şekilde, .cpp / hpp.

Soru

Yalnızca üstbilgi kitaplıkları genellikle geleneksel düzenden daha verimli kod ve yürütme süresi açısından daha akıllıca mıdır? Eğer öyleyse, bunun nedeni kapsamlı satır içi veya diğer optimizasyonlardan mı?

* - Bir başlıktaki fonksiyonun tanımlanması, derleyicinin herhangi bir çeviri biriminin derlenmesi sırasındaki uygulamayı görmesini sağlar ve pratik olarak satır içi kodu mümkün kılar


2
Çok sayıda modern C ++ bağlantısının (GCC, MSVC, ICC, vb.) Ayrı çeviri birimleri arasında kod satırlarında ne kadar başarılı olabileceğine şaşıracaksınız. Bağlayıcıları optimize etme beklentilerimi ne kadar zorlaştırdığı ve yine de satır içi olarak yönettiği (genellikle bir başlıkta satır içi veya uygulamayı statik olarak bağlı bir kütüphanede uygulama sağlamanın yardımcı olabileceği dylib bağlamları hariç) verilen verim perspektifinde "genel olarak hayır" derim. . Ancak, hem arayüz hem de uygulamada kararlı olmaları koşuluyla, yalnızca başlık kitaplıkları, yeni projelerde ne kadar kolay kullanılabildiklerinden seksi olabilir.

1
Bunun tam bir cevabı hakettiğini bilmiyorum, ancak yalnızca libs başlığının büyük bir yararı kurulum ve kullanım kolaylığı: Download, #include "lib.h (pp)", yapıldı.
WeRelic

Yanıtlar:


44

Yalnızca üstbilgi kitaplıkların C ++ için avantajlarından biri, ayrı olarak derlenmelerine gerek olmamasıdır

Hayır, bu tam tersi bir avantaj değil - kütüphanenin ana kısmı sadece bir kere değil, içerdiği sıklıkta derlenmelidir. Bu genellikle derleme zamanlarını arttıracaktır. Ancak, Vikipedi'de burada listelenen avantajlara atıfta bulunuyorsanız : bu makale, tüm yapım, paketleme ve dağıtım süreciyle ilgili olarak artan idari ek yükten bahsediyor.

C ve C ++ satır içi, yalnızca işlev bir başlık dosyasında tanımlanmışsa anlamlıdır *

Bu, derleyici / bağlayıcı sistemine bağlıdır, ancak çoğu C ve C ++ derleyicisi için bunun doğru olduğunu tahmin ediyorum.

Geleneksel olarak, C, .c / .h düzeni kullanılmıştır, burada başlığın çeviri biriminin asgari ortak arayüzünü temsil ettiği görülmektedir. Benzer şekilde, .cpp / hpp.

Bu çoğunlukla doğru. C ++ sınıfı başlıkları genellikle en az ortak arabirimden fazlasını içerir; bunlar genellikle çok sayıda özel şey de içerir. Bunu hafifletmek için, PIMPL deyimi gibi şeyler kullanılır. Bu, yalnızca bir başlık kitaplığının tersi gibi bir şeydir, gerekli başlık içeriğini en aza indirmeye çalışır.

Fakat asıl sorunuzu cevaplamak için: bu bir takas. Daha fazla kütüphane kodu başlık dosyalarına ne kadar çok koyarsa, derleyici hız kodunu o kadar fazla optimize etme şansına sahip olabilir (eğer bu gerçekten gerçekleşirse veya artış fark edilirse, tamamen farklı bir sorudur). Öte yandan, başlıklarda çok fazla kod derleme süresini artırıyor. Özellikle büyük C ++ projelerinde bu ciddi bir sorun haline gelebilir, John Lakos'un "Büyük Ölçekli C ++ Yazılım Tasarımı" konusuna bakın - kitap biraz eskimiş olsa da ve burada açıklanan sorunların bazıları modern derleyiciler tarafından ele alınmıştı; çözümler hala geçerlidir.

Özellikle, kararlı (üçüncü taraf) bir kütüphane kullanmıyorsanız, ancak projeniz sırasında kendi kütüphanelerinizi geliştiriyorsanız, derleme zamanları belirginleşir. Lib'ta bir şeyi her değiştirdiğinizde, tüm bağımlı birimlerin yeniden derlenmesine ve bağlanmasına neden olacak bir başlık dosyasını değiştirmeniz gerekir.

IMHO sadece başlık kütüphanelerinin popülaritesi, şablon meta programlamanın popülaritesinden kaynaklanmaktadır. Derleyicilerin çoğu için, şablonlanmış lib'lerin yalnızca başlıkları olması gerekir , çünkü derleyici yalnızca ana parametrelere tür parametreleri sağlandığında başlayabilir ve tam derleme ve optimizasyon için derleyicinin "her iki seferde de" görmesi gerekir - kitaplık kodu artı şablon parametre değerleri Bu, böyle bir kütüphane için herhangi bir "derlenmiş" derleme biriminin üretilmesini imkansız kılar (veya en azından zor).


6
Kısacası, yalnızca başlık kütüphaneleri daha verimli olmaktan daha uygundur ; ve C ++ herhangi bir standart paket yöneticisine sahip olmadığı için, bu benimsenmeye yardımcı olur.
Matthieu M.

6
@ MatthieuM: hayır, derlenen kod gerçekten bazen daha verimli olabilir ve şablon kütüphaneleri için sadece başlık tasarımı tipik olarak bir kolaylık meselesi değildir. Ve artan derleme zamanları kesinlikle daha uygun değildir.
Doktor Brown,

Başlıklardaki kısayol koduna sahip olmak gerçekten daha verimli bir derlenmiş koda yol açabilir, ancak bu tüm kodların başlıklarda olmasını gerektirmez ve bu nedenle IMHO'yu yalnızca başlık kitaplıklarından bağımsız kılar .
Matthieu M.

1
@MatthieuM .: Bu kesinlikle doğru, net, yine de "daha uygun" teriminin durumu iyi tanımlayamadığını düşünüyorum.
Doktor Brown,

3
Önceki işverenim için zayıflamış, eski bir işletim sistemi üzerine yerleştirilmiş büyük bir projede çalıştım ve bu durumlarda uzun derleme sürelerinin acısını çekebiliyorum. Başlık dosyalarına çok fazla doldurulmuş olan herkes acımasızca ele alınacaktı.
Fred Thomsen,

15

Peki, önce bazı varsayımlarınızı yıkalım:

  1. Yalnızca üstbilgi kitaplıkların C ++ için avantajlarından biri, ayrı olarak derlenmelerine gerek olmamasıdır.

Bir şeyleri ayrı ayrı derlemek, sadece bir parça değişirse potansiyel olarak her şeyi yeniden derlemek zorunda kalmamak anlamına gelir.
Yani bir avantaj yerine dezavantaj.

  1. C ve C ++ 'da satır içi yalnızca işlev bir başlık dosyasında tanımlanmışsa anlamlıdır *.

Evet, kalan tek etki tek tanım kuralınıninline istisnasıdır . Bu tanımların yine de herhangi bir şekilde farklı olup olmadığını size söyleyin.

Bu nedenle, bir fonksiyon derleme ünitesinin içindeyse, onu işaretleyin static. Bu aynı zamanda, satır içi işlevinin kullanılabilir olması gerektiğinden, satır içi işlemi daha olası kılar.
Yine de, en azından MSVC ++, gcc ve clang tarafından desteklenen link-time optimizasyonuna bir göz atın.

  1. Geleneksel olarak, C, .c / .h düzeni kullanılmıştır, burada başlığın çeviri biriminin asgari ortak arayüzünü temsil ettiği görülmektedir. Benzer şekilde, .cpp / hpp.

Eh, sadece asgari arayüzü sunmak, daha yüksek API ve ABI kararlılığı sağlamak ve derleme sürelerini en aza indirmek için kesinlikle amaçlardan biridir.

Özellikle C ++ sınıfları, tüm özel bitler başlığa sızdıklarından korunanlara göre türetmek isteyip istemediğinize göre, gerçekten de buna uygun değildir.

Tasarım deseni PIMPL , bu tür ayrıntıları azaltmak içindir.

Arayüz ve uygulamanın birbirinden ayrılmasının C ++ 'da tamamen başarısız olduğu kısım yine de şablonlardır.
Komite, dışa aktarılan şablonlarla bir şeyler yapmaya çalıştı ancak bu çok karmaşık ve gerçekten çalışmadığı için terk edildi.

Şimdi, yavaş ilerlemesine rağmen düzgün bir modül sistemi üzerinde çalışıyorlar . Bu derleme sürelerini ciddi şekilde azaltır ve ayrıca yüzeylerini azaltarak API ve ABI dengesini de arttırmalıdır.

Yalnızca üstbilgi kitaplıkları genellikle geleneksel düzenden daha verimli kod ve yürütme süresi açısından daha akıllıca mıdır? Eğer öyleyse, bunun nedeni kapsamlı satır içi veya diğer optimizasyonlardan mı?

Yalnızca üstbilgi kitaplıkları, kod boyutunda ve yürütme zamanında daha verimli olabilir; ancak bu, kitaplığın paylaşılıp paylaşılmadığına, ne kadarının kullanıldığına, hangi şekillerde kullanılacağına ve satır içi yapmanın bu belirli durumda belirleyici bir kazanım sağlayıp sağlamadığına bağlı olarak değişir.

Ve inlining'in optimizasyon için çok önemli olmasının sebebi, inline etmenin kendisinin çok büyük bir destek olması değil, sürekli yayılma ve daha fazla optimizasyon fırsatları nedeniyle ortaya çıkmasıdır.

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.