C ++ geliştirmede STL'den vazgeçmek pratik midir? [kapalı]


19

Bazı bölgelerde (örneğin oyun endüstrisi) biliyorum, STL önerilmez. Yani sorum şu: bazı durumlarda STL kullanmamak gerçekten iyi bir uygulama mı? Öyleyse, modern C ++ 'ın STL'sini kullanmamanın en büyük nedenleri nelerdir?



Bazı meslektaşlarım, yineleyicinin hata ayıklamayı zorlaştırdığını iddia ediyor, çünkü bazen adım atmak kolay değil ve bu da lambda için geçerli. Yanıtınız nedir?
KaptanJH

Hata ayıklama sırasında bir şeyleri atlamak için, bkz. Örneğin: stackoverflow.com/questions/2062881/…
Martin Ba

Bu iyi bir soru gibi görünüyor. Belki birisi "Bir proje neden STL'yi kullanmamayı tercih eder?"
Matthew James Briggs

Yanıtlar:


25
  • Sadece bir geçerli sebep düşünebilirim ve bu çok nadir: Zor gerçek zamanlı. Standart kütüphanedeki birçok şey hafızayı dahili olarak ayırır ve bu, gerçek zamanlı zor uygulamalar için yeterince belirleyici değildir, bu nedenle bunlardan kaçınılmalıdır. Bu uygulamalar genellikle oldukça basittir, ancak çok titiz inceleme ve testler nedeniyle gelişmeleri orantısızdır.

  • Geçersiz, ancak çok yaygın bir neden düşünebilirim: Hesaplama karmaşıklığını anlamayan, STL'yi kötüye kullanan ve kütüphaneyi suçlayan geliştiriciler.

    STL, çalışma zamanında genellikle ya geri arama işaretçileri olan C tarzı çözümlerden ya da sanal yöntemlerle polimorfizm tabanlı çözümlerden daha hızlıdır ( ayrıca bkz. Bu Bjarne Stroustrup'un açılış notu ). Ancak, geliştirici verilen karmaşıklık özelliklerini anlamadığında ve bazı karmaşık nesnelerin vektörlerinin vektörü gibi bir şey oluşturarak kütüphaneyi kötüye kullandığında (C ++ 11'de artık bir sorun değildir!), Performans sorununa neden olur ve kendilerini savunur "gördüğünüz gibi, vektörler oldukça yavaştır", standart kütüphanenin yavaş olduğu algısına neden olabilir. Ve yöneticiler böyle bir algı aldığında, organizasyonda çok uzun yaşayabilir.

  • Açıkçası, hedeflediğiniz platformun desteklemediği bir şey kullanamazsınız. Ancak şu anda en yaygın dört mobil platformlar (Android, iOS Bada ve eski WinCE) hedefleyen ve standart kütüphane ve bazı parçaları kullanın edilmektedir Boost hepsinde.

    Standart kütüphanenin çoğu, Microsoft tarafından WinCE'nin başında desteklenmiyordu (IIRC iostreams yalnızca Visual Studio 2005 ile çıktı), ancak bunun yerine çok önce STLport kullanmak mümkün oldu . Ve genellikle bunu herhangi bir şeye derlemek için alabilirsiniz. Ben de bu nedenle geçersiz diyeceğim.

    Ayrıca, oldukça uzun bir süre "STL" değil, ANSI C ++ Standart Kütüphanesi. Dilin kendisini tanımlayan aynı standart belge ile tanımlanır. Bunu desteklemeyen hiçbir şey C ++ olarak adlandırılmayı hak etmiyor.


6
İlk argüman (gerçek zamanlı) Standart Kütüphanenin STL bölümlerine özgü değildir. sprintfgenellikle bellek ayırır. Gerçek zamanlı platformlarda, standart kütüphane işlevlerinin de belirleyici sınırları vardır. Bu, gerçek zamanlı C ++ uygulamalarını zorlaştırır: Küçük bir C standart kitaplığından daha fazla iş olan tüm bir C ++ standart kitaplığını dikkatlice geliştirmeniz gerekir.
MSalters

@MSalters: Elbette, birçok şey gerçek zamanlı gereksinimler altında kullanılamaz. İstisnalar gibi bazı dil özellikleri bile yapamaz. Yine de C ++ bu sistemler için mükemmel bir dildir, çünkü performansı ve hassas kontrolü güçlü korumalarla birleştirebilir (RAII bunun için en önemli özelliktir).
Jan Hudec

@JanHudec: Aslında, bu yüzden STL parçaları sadece C ++ 'ın "barındırılan" uygulamaları için gereklidir.
MSalters

7

Uzun yıllardır STL ve güçlendirmeyi kullanıyorum. Onu terk edip özel aletlerimi kullanmak istersem, motivasyon şöyle olurdu:

  1. Derleme süresini azaltma (% 75). Sadece iostreams dahil olmak üzere modülünüze 1 milyon satır kod ekleyebilirsiniz. Evet önceden derlenmiş üstbilgiler çok yardımcı olur, ancak yine de büyük projelerde derlemeyi çok yavaşlatır. Uzun vadede, üzerinde çalışan herkes için çok zaman harcıyor.
  2. Verim. (% 25) STL genel olarak çalışmak için yazılmıştır, ancak yapılarınızı tam istediğiniz gibi çalışacak şekilde optimize edebilirsiniz. Örneğin, milyonlarca kısa dizeye sahip bir veri yapılarınız olabilir. Boost :: small_vector (küçük statik yerel veri vektörü, yalnızca daha büyük dizeler için dinamik ayırma) ilkesine dayalı olarak özel dize sınıfını kullanmak çok daha hızlı olabilir, bu tür değişiklikler kodun kritik bölümlerini çok daha hızlı çalıştırabilir.

1
TOA zaten yaygın.
Deduplicator

gelecek nesiller için: TOA -> küçük dize optimizasyonu, yani çoğu (tümü?) std :: dize uygulamaları küçük dizeleri yığının üzerinde tutar ve gerekirse
mavi

Derleme süreleri büyük
user1754322

4

C ++ standart şablon kütüphanesini kullanmamanın büyük bir geçerli nedeni var: Hedef platformlarınızdan birinin tam olarak uyumlu bir uygulaması yok (veya hiç uygulaması yok) ve bir tane almayacağını biliyorsunuz önümüzdeki yıllarda.


3
Aka, "sahip olmadığında kullanma" gerçekten mantıklı. :)
Xeo

4
C ++ 03 standart kitaplığının yalnızca ANSI C89 kitaplığı açısından uygulanacak şekilde tasarlandığı göz önüne alındığında, en azından STLPort'u alamadığınız herhangi bir platform var mı?
Jan Hudec

@JanHudec STL'siz platformlar olduğuna inanıyorum çünkü her şeyi halletmek için yeterli belleğe sahip değiller. Genellikle diğer bazı C ++ işlevlerini de (örn. İstisnalar) yoktur.
Sulthan

2
@Sulthan: Mikrodenetleyiciler için anlıyorum, ama bunlar genellikle "zor gerçek zamanlı" kategorisine giriyor. Başka bir şey için, bu çoğunlukla önyargılardır, çünkü STL genellikle hem bellek hem de performans açısından el yapımı kod kadar etkilidir. Çok fazla satır içi çizgi daha büyük bir ikiliğe neden olabilir, ancak bu, bazı performans maliyetlerinde (elle hazırlanmış bir çözümün de sahip olacağı) dikkatli bir şekilde uygulanmasıyla önlenebilir. Eksik istisnalar da önyargı veya tembelliktir, çünkü ABI istisnasını tanımlamak ve uygulamak çaba gerektirir.
Jan Hudec

4

Karmaşıklık (uygulama verimliliği) hakkında bilmiyorum ama std olanlar yerine Qt kapları ve dizeleri yaygın olarak kullanıyorum ve iyi çalışıyorlar. Ayrıca setlerin ve listelerin Qt uygulamasının kullanımını daha kolay buluyorum.

Dolayısıyla, ihtiyaçlarınıza uygun başka bir kütüphane kullanabiliyorsanız STL'den vazgeçmek pratik olabilir.


2
Qt eşdeğeri, a) mevcut veya b) herhangi bir iyi olan hiçbir STL uygulaması olmadığında geri yaratılmıştır. Hala kullanılmalarının tek nedeni bu, bugünün STL'sine karşı hiçbir şey.
gbjbaanb

1
@Giorgio: Sorun, birden fazla kütüphaneyi birleştirdiğiniz karmaşık uygulamalarda. Standart olan STL kapları bir lingua franca oluşturur . Daha doğrusu, yaptıkları sözleşmelerdir. En iyi bilinen örnek Boost'tur. STL kaplarında çalışabilir. ayrıca Qt kapları üzerinde de çalışabilir, ancak yalnızca QList<T>::iterator
Qt'nin

3
Onu küçümsemedim, ama bir neden görüyorum: Bu soruya cevap vermiyor. STL yerine kullanılacak şeyler olduğunu söyledin, tamam, ama bu STL'yi önlemek için bir neden değil. STL'yi önlemek için herhangi bir nedenin yanı sıra muhtemelen Qt, MFC ve diğer kütüphaneler için de geçerlidir.
Jan Hudec

3
@NoOne: Snakecase değil, deve için alıştığınızı anlıyoruz, ancak bu ikincisini daha da kötüleştirmiyor. Ve eleştirdiğiniz üç işlev adından ilki, c-dizeleriyle ilgisi olan herkes için mükemmel bir tanımlayıcıdır ve diğer ikisi C'den miras alınır, bunları tartışmayacaktır.
Tekilleştirici

1
@NoOne: Dediğim gibi, CamelCase ile daha rahat olduğunuzu tamamen anlıyorum.
Tekilleştirici

3

Patrick, STL'nin tamamını kullanmamanın nedeninden bahsetti , yani platformlarınızda bir tane yok.

Sonuçta sorunun noktayı kaçırdığını düşünüyorum. Çoğunlukla ya hep ya hiç bir karar değil, seç ve seç. Kapsayıcılar ve algoritmalar ile gitmeye karar verebilir, ancak dizeler ve i / o için Std Lib dışında bir şey kullanmaya karar verebilirsiniz.


3

Ağır bir neden olmadığı sürece pratik değildir. Düşünebileceğim bu nedenlerden bazıları, STL'nin (veya standart kütüphanenin herhangi bir bölümünün) sadece kısmi veya eksik uygulamasını veya etrafta dolaşmanız gereken bir kaynak sınırlamasını (bellek, CPU hızı, depolama, ...) içerir. gerçekleştirmeniz gereken şeylere uygun kendi araçlarınızı yuvarlayın.

Oyun endüstrisinde çoğu (hatta bir dereceye kadar küçük) stüdyoların iç kütüphaneleri ve hedef platform için yüksek düzeyde uyarlanmış ve bazı durumlarda engnie hatta oyunun kendisini hedefleyen birçok standart kütüphane parçası uygulamaları vardır. Basitçe söylemek gerekirse konsollar için bir oyun geliştirirken donanım günümüz standartlarına göre çok sınırlıdır. Bir nedenden ötürü binlerce ve binlerce el yapımı montaj hattı var. Kodunuzdaki her türlü kaynak ayak izini en aza indirgemek çok önemlidir, böylece oyun daha hızlı çalışır, bu da oyun dünyasında (veya daha büyük bir dünyada) daha iyi bir ürün elde edilmesini sağlar.

"Her başarılı oyun, kendi bağlantılı liste uygulamanızı başlatarak başlar."


1
Her başarılı oyunun standart kütüphaneyi kullanarak kod yazarak ve daha sonra sadece oyun kapsamlı bir şekilde profillendikten sonra kodu optimize ederek başlayacağını hayal ediyorum. Optimizasyon ihtiyacı olan şeyleri belirten profil verisine sahip olmadan önce optimizasyon yapmak anlamsızdır.
Cromulent

Doğru. Son cümle sadece 90'lı yılların başlarında oyun yazmanın "eski" yolunda bir oyundu, C ++ yaygın olarak konuşlandırılmadığında ve montaj + C gitmenin yoluydu. Belki daha açık bir şekilde ifade etmeliydim. Konsollardaki oyun endüstrisi için de geçerlidir, çoğu algorthms ve veri yapısı varsayılan olarak elle yazılır, çünkü her bayt ve döngü önemlidir (evet, sürdürülebilirlik / taşınabilirlik / herhangi bir şey pahasına bile olsa).
zxcdw

2
Söylemek gerekir ki, daha çok üzerinde yaşayan eski bir deneyim. Modern optimizer genellikle basit bakımı kolay koddan programcının elle yapacağından daha iyi bir montaj oluşturur ve STL veya Boost gibi genel şablonlar genellikle her şeyi elle özel olarak kaplamak kadar verimli bir kod olarak sıralanır. Ancak durum böyle olmadığı zamanlarda başlayan bir sürü kod var ve o günlerde ticareti öğrenen ve artık mantıklı olmasa da bu şekilde çalışmaya devam eden birçok insan var.
Jan Hudec

2
@JanHudec Mesele şu ki, uygulamaların (ve davranışların da, bulaşmanın) görev için çok uyarlanması gerekiyor. Sadece burada ve orada birkaç referans bayt yedekleyemezsiniz (referansın yerini mahveder), girişi doğrulamak için birkaç dalı bırakabilirsiniz (şube yanlış tahminleri ve talimat önbellek özledim) ve derleyicinin veri yapılarınızı nasıl vektörleştireceğini bildiğini varsayalım SIMD'den en iyi şekilde yararlanmak için en uygunudur (olmaz veya en azından denediği şeyin doğru olduğunu doğrulamanız gerekir). Tabii ki bir PC'ye gerçek zamanlı yazılım yazmak o kadar sıkı değil, her zaman daha hızlı bir CPU atabilirsiniz. Konsollarda değil.
zxcdw
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.