STL veya Qt kapları?


185

Qt kapları (kullanmanın avantajları ve dezavantajları nelerdir QMap, QVectorbunların STL eşdeğer üzerinde, vs.)?

Qt tercih etmek için bir neden görebilirsiniz:

  • Qt kapları, Qt. Örneğin, a QVariantve sonra a'yı doldurmak için kullanılabilirler QSettings(ancak bazı sınırlamalarla, yalnızca QListve QMap/ QHashveya anahtarları dizeler kabul edilir).

Başka var mı?

Düzenleme : Uygulamanın Qt.

Yanıtlar:


135

Ben std::(w)stringsadece STL kapları kullanarak ve Qt eşdeğerlerine / Qt eşdeğerlerine dönüştürerek başladım, ama daha önce geçiş QStringyaptım ve Qt kaplarını giderek daha fazla kullandığımı fark ettim.

Dizeler söz konusu olduğunda, QStringkarşılaştırıldığında çok daha eksiksiz bir işlevsellik sunar std::basic_stringve tamamen Unicode farkındadır. Ayrıca, yoğun bir şekilde kullandığım verimli bir COW uygulaması da sunuyor .

Qt konteynerleri:

  • Qt'nin makrosunu (bir kopyasını yapar) kullanırken ve meta-tipler veya sinyaller ve yuvalar QStringkullanırken son derece yararlı olan COW uygulamasını aynı şekilde sunun foreach.
  • STL stili yineleyicileri veya Java stili yineleyicileri kullanabilir
  • ile yayınlanabilir QDataStream
  • Qt'nin API'sında yaygın olarak kullanılır
  • işletim sistemlerinde istikrarlı bir uygulamaya sahip olmak. Bir STL uygulaması C ++ standardına uymalıdır, ancak istediği gibi yapmakta özgürdür (bkz. std::stringCOW tartışması). Bazı STL uygulamaları özellikle kötüdür.
  • TR1 kullanmadığınız sürece kullanılamayan karma sağlama

QTL, STL'den farklı bir felsefeye sahiptir, bu da J. Blanchette tarafından iyi özetlenmiştir : "STL'nin konteynerleri ham hız için optimize edilirken, Qt'ın konteyner sınıfları kolaylık, minimum bellek kullanımı ve minimum kod genişletme sağlamak için dikkatle tasarlanmıştır."
Yukarıdaki bağlantı, QTL'nin uygulanması ve hangi optimizasyonların kullanıldığı hakkında daha fazla ayrıntı sağlar.


12
Yeni standart c ++ 0x COW hemen hemen tablodan.

16
re: "dikkatle tasarlanmış [...] minimum bellek kullanımı". Pazarlamaya inanmamalısınız. QList<double>Kendiniz görmek için bellek kullanımı için 32 bit mimari profil .
Marc Mutz - mmutz

11
"Aynı zamanda verimli bir COW uygulaması da sunar": COW çok iş parçacıklı uygulamalar söz konusu olduğunda o kadar verimli değildir ...
Grizzly

5
@ MarcMutz-mmutz QVectoryerine profil yapmaya çalışın QList. QList'in nesnelerde işaretçileri saklamak için tasarlandığı oldukça Qt açıklaması var. Böylece dinamik olarak oluşturulan her bir çift öğe ve bu öğeye işaretçi saklanır QList. QList, vektör ve bağlantılı liste arasında "orta" kap olarak tasarlanmıştır. Bellek / performans açısından kritik durumlar için tasarlanmamıştır.
Dmitry Sazonov

2
@ user1095108 Bunda yanlış bir şey yok. Git stl kullanın. Bazılarımız hızlı bir şekilde doğru kod yazmayı tercih ediyoruz. Bunda da yanlış bir şey yok.
weberc2

178

Bu soruyu cevaplamak zor. Gerçekten felsefi / öznel bir argümana kadar kaybolabilir.

Söyleniyor ki...

"Roma'da ... Romalılar gibi yapın" kuralını öneriyorum

Yani eğer Qt ülkesindeyseniz, Qt'ianlar gibi kodlayın. Bu sadece okunabilirlik / tutarlılık endişeleri için değildir. Her şeyi bir stl kapsayıcısında saklarsanız, tüm bu verileri bir Qt işlevine iletmeniz gerekir. Gerçekten bir şeyleri Qt kaplarına / dışına kopyalayan bir grup kodu yönetmek istiyor musunuz? Kodunuz zaten büyük ölçüde Qt'ye bağımlıdır, bu yüzden stl kaplarını kullanarak artık daha "standart" hale getirdiğiniz gibi değildir. Ve yararlı bir şey için her kullanmak istediğinizde bir kabın amacı nedir, ilgili Qt kabına kopyalamanız gerekir?


1
Tamamen doğru + 1'ledim, sorumu açıklamaya çalıştım ("Qt'yi tercih etmek için bir neden görebilirim"), bu yüzden biraz düzenledim. Teşekkürler
Julien-L

Kesinlikle iyi dedi. QT yapıyorsanız, QT şeylerini kullanın! Bir QT uygulaması açıp QT ve STL'nin birbirinin yerine kullanıldığını gördüğünde bakımcının "WTF" momentini hayal edin. Bu (gereksiz) bir kabus olabilir.
It'sPete

5
@ It'sPete STL standardın bir parçasıdır; QT değil. Standardı kullanan herhangi bir kod asla "WTF" momentini tetiklememelidir.
Alice

6
Romalılar esirlerini Kolezyum'a koydular ve sonra aslanlarla avladılar. Daha iyi biliyorsanız, yerel alışkanlıklara uymayın. Roma İmparatorluğu'ndaki Modern İnsan için olduğu gibi Qt için de bu doğru ...
Marc Mutz - mmutz

1
@mmutz diyorsun ki kötü bir şeymiş gibi, o Kolezyum'da bulduğum bazı kodları koymak ve şovu izlemek istiyorum
slf

65

Qt kapları, STL kaplarından daha sınırlıdır. STL'lerin nerede daha üstün olduğuna dair birkaç örnek (bunların hepsini geçmişte vurdum):

  • STL standartlaştırılmıştır, her Qt sürümü ile değişmez (Qt 2 QList(işaretçi tabanlı) ve QValueList(değer tabanlı); Qt 3 vardı QPtrListve QValueList; Qt 4 artık var QListve hiçbir şekilde QPtrList ya da benzeri değil QValueList).
    Qt kapsayıcılarını kullansanız bile , tekrar taşımadan kaçınmak için STL uyumlu API alt kümesini (yani push_back(), değil append();, front()değil first(), ...) kullanın. 5. Qt2-> 3 ve Qt3-> 4 geçişleri, Qt kapsayıcılarındaki değişiklikler en fazla kod karmaşası gerektiren değişiklikler arasındaydı.
  • STL iki yönlü kaplar tümüne sahip rbegin()/ rend()ileri yineleme ters yineleme simetrik hale. Tüm Qt kapları bunlara sahip değildir (birleştirici olanlar yoktur), bu nedenle ters yineleme gereksiz derecede karmaşıktır.
  • STL kapları insert(), farklı, ancak uyumlu yineleyici türlerinden, std::copy()daha az sıklıkla gerekli hale gelen aralığa sahiptir .
  • STL kapsayıcıları, Qt ( için gerekli çatal ) ile karşılaştırıldığında Allocatorözel bellek yönetimini önemsiz hale getiren (typedef gerekli) bir şablon bağımsız değişkenine sahiptir . EDIT 20171220 : Bu, C ++ 11 ve C ++ 17, krş. örneğin, John Lakos'un konuşması ( bölüm 2 ).QLineEdits/QString/secqstring/
  • Buna eşdeğer bir Qt yoktur std::deque.
  • std::listvardır splice(). Kendimi kullanırken std::listbulduğumda buna ihtiyacım var splice().
  • std::stack, std::queueOlarak düzgün, altta yatan bir kap araya ve bunun devralır yok QStack, QQueueyok.
  • QSetgibi std::unordered_set, değil std::set.
  • QListBir olan sadece tuhaf .

Yukarıdakilerin çoğu Qt'de oldukça kolay bir şekilde çözülebilir , ancak Qt'deki konteyner kütüphanesi şu anda geliştirme odağı eksikliği yaşıyor gibi görünüyor.

EDIT 20150106 : Qt 5 konteyner sınıflarına C ++ 11 desteği getirmek için biraz zaman geçirdikten sonra, çalışmaya değer olmadığına karar verdim. C ++ standart kütüphane uygulamalarına konulan çalışmaya bakarsanız, Qt sınıflarının asla yetişmeyeceği oldukça açıktır. Şimdi Qt 5.4 yayınlandı ettik veQVector hala reallocations üzerinde unsurları hareket etmez, yokemplace_back()ya rvalue-push_back()... Biz de son zamanlarda reddedilenQOptionalbekliyor, sınıf şablonustd::optionalyerine. Aynı şekildestd::unique_ptr. Umarım bu eğilim devam eder.


3
Huh. İzlenim altında ben QList oldu eşdeğerdir std::deque. Açıkçası, belgeleri gözden kaçırmamalıydım.
Dennis Zickefoose

QVectoretti crbeginQt 5.6 beri ve arkadaşlar
Bart Louwers

@Alex: doğru, kolay olanları ekledim, ancak Qt kapsayıcılarının hepsinde henüz yok, (çünkü izinsiz bırakıldığında yerine dönen std::reverse_iteratorkırık QHash/ QMapyineleyiciler üzerinde kullanmıyorsunuz ). Çözülemez bir şey, ama benim bkz DÜZENLEMEYİ 2015 denmapped_typevalue_type
mmutz - Marc Mutz

@ MarcMutz-mmutz Açıkladığınız için teşekkür ederiz.
Bart Louwers

Listeye örneğin endeksi olarak QVectorkullandığı gerçeğini eklemeye değer olabilir int, böylece 31 bit boyutları sınırlandırır (64 bit sistemlerde bile). Dahası, INT_MAX1 bayttan daha büyük boyutlu öğeleri bile depolayamaz . Örneğin x86_64 Linux gcc'de .size()sahip olabileceğim en büyük QVector<float>şey 536870907 element (2²⁹-5) iken, std::vector<float>4294967295 elementi (2³²-1; RAM için eksiklik nedeniyle daha fazla denemedim) (bu boyut zaten 16 GiB alır) ).
Ruslan

31

Bu iddiaları gerçek ölçülebilir olaylara ayıralım:

  • Daha hafif: Qt kapları STL kaplarından daha az bellek kullanır
  • Daha güvenli: Qt konteynerlerin yanlış kullanılması için daha az fırsatı vardır
  • Daha kolay: Qt konteynırları daha az entelektüel bir yük sunar

Daha kolay

Bu bağlamda öne sürülen iddia, java tarzı yinelemenin STL stilinden bir şekilde "daha kolay" olması ve bu nedenle bu ek arayüz nedeniyle Qt'nin daha kolay kullanılmasıdır.

Java Stili:

QListIterator<QString> i(list);
while (i.hasNext())
    qDebug() << i.next();

STL Tarzı:

QList<QString>::iterator i;
for (i = list.begin(); i != list.end(); ++i)
    qDebug << *i;

Java yineleyici stili biraz daha küçük ve daha temiz olma avantajına sahiptir. Sorun şu ki, bu aslında STL tarzı değil.

C ++ 11 STL Stili

for( auto i = list.begin(); i != list.end(); ++i)
    qDebug << *i;

veya

C ++ 11 foreach tarzı

for (QString i : list)
    qDebug << i;

Bu o kadar basittir ki, başka bir şey kullanmanız için hiçbir neden yoktur (C ++ 11'i desteklemediğiniz sürece).

Benim favorim ise:

BOOST_FOREACH(QString i, list)
{
    qDebug << i;
}

Gördüğümüz gibi, bu arayüz bize zaten şık, aerodinamik ve modern bir arayüzün üstünde ek bir arayüz dışında hiçbir şey kazanmıyor. Zaten kararlı ve kullanılabilir bir arabirimin üzerine gereksiz düzeyde bir soyutlama mı ekliyorsunuz? Benim "kolay" fikrim değil.

Ayrıca, Qt foreach ve java arayüzleri ek yük ekler; yapıyı kopyalar ve gereksiz düzeyde bir dolaylama sağlar. Bu çok fazla görünmeyebilir, ancak neden bu kadar basit olmayan bir arayüz sağlamak için bir ek yük katmanı eklemelisiniz? Java bu arabirime sahiptir çünkü java'da aşırı yükleme yoktur; C ++ yapar.

Daha güvenli

Qt'nin verdiği gerekçe, ne örtük ne de bir sorun olan örtük paylaşım problemidir. Ancak paylaşmayı da içerir.

QVector<int> a, b;
a.resize(100000); // make a big vector filled with 0.

QVector<int>::iterator i = a.begin();
// WRONG way of using the iterator i:
b = a;
/*
Now we should be careful with iterator i since it will point to shared data
If we do *i = 4 then we would change the shared instance (both vectors)
The behavior differs from STL containers. Avoid doing such things in Qt.
*/

İlk olarak, bu örtük değildir; açıkça bir vektörü diğerine atarsınız. STL yineleyici belirtimi, yineleyicilerin kaba ait olduğunu açıkça gösterir, bu nedenle b ve a arasında paylaşılan bir konteyner tanıttık. İkincisi, bu bir sorun değil; yineleyici belirtiminin tüm kurallarına uyulduğu sürece, kesinlikle hiçbir şey yanlış gitmez. Bir şeylerin yanlış gittiği tek zaman burada:

b.clear(); // Now the iterator i is completely invalid.

Qt bunu sanki bir şey ifade ediyormuş gibi belirtir, çünkü bu senaryodan bir sorun çıkmış gibi. Öyle değil. Yineleyici geçersiz kılınmıştır ve tıpkı birden fazla ayrık alandan erişilebilen her şey gibi, bu da tam olarak böyle çalışır. Aslında, Qt'daki Java stili yineleyicilerle kolayca ortaya çıkacaktır, çünkü burada ve diğer birçok alanda belgelendiği gibi bir antipattern olan örtük paylaşıma büyük ölçüde güvenmektedir . Bu "optimizasyonun" çok iş parçacılığa doğru giderek daha fazla hareket eden bir çerçevede kullanılması özellikle garip görünüyor, ama bu sizin için pazarlama.

çakmak

Bu biraz daha hileli. Yazarken Kopyala ve Örtülü Paylaşım ve Büyüme Stratejilerinin kullanılması, kabınızın herhangi bir zamanda ne kadar bellek kullanacağı konusunda garanti vermeyi çok zorlaştırır. Bu, size güçlü algoritmik garantiler veren STL'den farklıdır.

Bir vektör için boşa giden alanın minimal sınırının, vektörün uzunluğunun kare kökü olduğunu biliyoruz , ancak bunu Qt'de uygulamanın hiçbir yolu yok gibi görünüyor; destekledikleri çeşitli "optimizasyonlar" bu çok önemli yer tasarrufu özelliğini engelleyecektir. STL bu özelliği gerektirmez (ve çoğu daha israflı olan iki kat büyüme sağlar), ancak gerekirse en azından bu özelliği uygulayabileceğinizi not etmek önemlidir.

Aynı durum, kullanılan alanı önemli ölçüde azaltmak için XOr linkini kullanabilen çift bağlantılı listeler için de geçerlidir. Yine, büyüme ve COW gereksinimleri nedeniyle Qt ile bu mümkün değildir.

COW gerçekten daha hafif bir şey yapabilir, ancak boost tarafından desteklenen Intrusive Container'lar da kullanılabilir ve Qt bunları önceki sürümlerde sık sık kullandı, ancak artık kullanılmadıkları, güvensiz oldukları ve bir yük yükledikleri için artık kullanılmıyorlar programcı üzerinde. COW çok daha az müdahaleci bir çözümdür, ancak yukarıda belirtilen nedenlerden dolayı çekici değildir.

Herhangi bir zamanda ne kadar bellek harcayacağınızı bilmenin ek avantajı ile Qt konteynırlarından aynı veya daha düşük maliyetli STL kaplarını kullanamamanızın bir nedeni yoktur. Ne yazık ki, ham bellek kullanımında ikisini karşılaştırmak imkansızdır, çünkü bu tür karşılaştırmalar farklı kullanım durumlarında çılgınca farklı sonuçlar gösterecektir, bu da STL'nin düzeltmek için tasarlandığı tam bir problemdir.

Sonuç olarak

Kopyalama maliyeti koymadan mümkün olduğunda Qt Kapları kullanmaktan kaçının ve mümkünse STL tipi yinelemeyi (belki bir sarıcı veya yeni sözdizimi yoluyla) kullanın.


4
Puanlarınız büyük ölçüde geçerlidir, ancak bazı yanıltıcı bilgiler vardır: Adding an unnecessary level of abstraction on top of an already stable and usable interface? Not my idea of "easier".Qt'nin Java stili yineleyicileri C ++ 11'e eklenmemiştir; Ondan önce gelirler. Her neyse Qt foreach(QString elem, list), C ++ 11'in foreach veya BOOST_FOREACH kadar kolaydır ve C ++ 11 öncesi derleyicilerle çalışır.
weberc2

@ weberc2 Kafası karıştı; Qt'nin Java stili yineleyicileri C ++ (C ++ 11 değil) yineleyicilerinin üstüne eklenir. Arayüzü şişiren ek bir soyutlama katmanı (ve gereksiz bir katman), bu daha kolay değil. Ve Qt için foreach, BOOST_FOREACH kadar kolay değildir, çünkü özellikle güvenli değildir ve aynı destek genişliğine sahip değildir (BOOST_FOREACH, QT'de foreach'in C + istediği herhangi bir C ++ sürümü için herhangi bir aralığa uygulanabilir. +03 uyumluluğu). QT'nin ön tahmini her ne pahasına olursa olsun önlenmelidir.
Alice

So, as we can see, this interface gains us nothing except an additional interface, *on top of* an already sleek, streamlined, and modern interface. Adding an unnecessary level of abstraction on top of an already stable and usable interface? Not my idea of "easier".(Vurgu benim) Bize foreach'in C ++ 11 ve BOOST sürümlerini gösterdikten hemen sonra bunu söylediniz, Qt sürümü bu ikisinden birinden oluşmuş gibi görünüyor, bu AFAICT değil. Eminim kastettiğiniz bu değil, ama işte böyle çıkıyor. Dolayısıyla "yanıltıcı bilgi".
weberc2

It's an additional layer of abstraction (and an unnecessary one) that bloats the interface, which is not easier.Neyle kıyasladığınız hala belli değil. C ++ 03 yineleyicileri? C ++ 11 yineleyicileri? BOOST_FOREACH? Yukarıdakilerin hepsi?
weberc2

1
Sadece söylüyorum, hangi yineleme yöntemine başvurduğunuz konusunda genellikle çok belirsizsiniz. Açık olduğunuzu ve dilinizin makul olduğunu düşündüğünüze inanıyorum, ancak belirtmeyi reddetmek garip görünüyor. Sanırım katılmıyorum kabul ediyorum.
weberc2

23

STL kapları:

  • Performans garantileri var
  • Performans garantisi olan STL algoritmalarında da kullanılabilir
  • Boost gibi üçüncü taraf C ++ kütüphaneleri tarafından kullanılabilir
  • Standarttır ve tescilli çözümleri geçebilir
  • Algoritmaların ve veri yapılarının genel programlamasını teşvik etmek. STL'ye uygun yeni algoritmalar ve veri yapıları yazarsanız, STL'nin halihazırda sunduğu şeylerden ücretsiz olarak yararlanabilirsiniz.

5
STT desteğiyle (varsayılan) Qt'yi derlemeniz koşuluyla, standart olmak dışında yukarıdakilerin tümü QTL için de geçerlidir. STL desteği, yineleyici işlevlerini, kapsayıcı tip tanımlarını (const_iterator, vb.), Dönüştürme işlevlerini (STL'ye / STL'den) içerir.
rpg

2
Qt tescilli değil
txwikinger

3
@rpg Hemen hemen hepsi QTL için doğru değil; QTL, güçlü bir performans garantisine sahip değildir (geçmişte kolayca kırdıkları için), STL uyumlu değildir (tersine çevrilmez ve bu nedenle çoğu destek tarafından kullanılamaz), standart değildir (sürümler arasında sürekli değişir) ve jenerik programlamayı teşvik etmemektedir (örneğin, ayırıcılar için şablon argümanları yoktur).
Alice

15

Qt kapsayıcılarında yazma-kopyalama deyimi kullanılır.


2
+1, performans ve kaynak açısından önemli bir avantaj olabilir
RedGlyph

32
Veya önemli bir dezavantaj olabilir. Bkz. Gotw.ca/publications/optimizations.htm
Kaz Dragon

3
Atomik refcount oldukça iyi gözüküyor: labs.trolltech.com/blogs/2006/10/16/…
rpg

STL kapları, performans garantilerini ve spesifikasyonlarını karşıladıkları sürece mevcut olan deyimleri kullanmakta serbesttir. COW, C ++ 11 / C ++ 14 STL altında bile geçerlidir.
Alice

1
@Alice COW çoğu zaman geçerli bir uygulama değildir, çünkü neredeyse her durumda standardın karmaşıklığını ve yineleyici geçerlilik garantisini ihlal eder. COW ile uygulanabilecek birkaç sınıftan biri std::basic_string, standart C ++ 11 ile bu uyuşmazlığı sağlamak için harekete geçti.
Tiago Gomes

9

Ana sorunlardan biri, Qt API'sinin Qt kapsayıcılarında veri sağlamanızı beklemesidir, bu nedenle ikisi arasında ileri geri dönüştürmek yerine Qt kapsayıcılarını da kullanabilirsiniz.

Ayrıca, zaten Qt kapsayıcılarını kullanıyorsanız, STL başlık dosyalarını dahil etmeniz ve potansiyel olarak STL kitaplıklarına bağlamanız gerekmeyeceğinden, bunları özel olarak kullanmak biraz daha uygun olabilir. Ancak, alet zincirinize bağlı olarak, bu yine de olabilir. Tamamen tasarım açısından bakıldığında tutarlılık genellikle iyi bir şeydir.


1
Qt ile ara yüzün genel olarak büyük ölçüde fazla tahmin edildiği durumlar dışında STL kullanan gerçek bir uygulamada STL ve Qt kapları arasında "ileri geri dönüşüm" yapmak zorunda olduğunuz oran. Çoğu zaman (Qt kullanan) sunum katmanına gelen / gelen bazı std :: dönüşümü yapar ve kapsayıcı anahtarını ücretsiz olarak alırsınız. İlgili taraflar kendileri görmek için projects.kde.org/projects/kde/kdepim/repository/revisions/… adresine göz atabilirler .
Marc Mutz - mmutz

8

Birlikte çalıştığınız veriler çoğunlukla Qt tabanlı kullanıcı arayüzünü kullanmak için kullanılıyorsa, kesinlikle Qt kapları kullanın.

Veriler çoğunlukla uygulamada dahili olarak kullanılıyorsa ve hiçbir zaman Qt'dan uzak durmanız ve performans sorunlarını engellemeniz olası değilse, Qt kapsayıcılarını kullanın, çünkü kullanıcı arayüzüne giden veri parçalarıyla başa çıkmayı kolaylaştıracaktır.

Veriler çoğunlukla yalnızca STL kaplarını bilen diğer kitaplıklarla birlikte kullanılıyorsa, STL kaplarını kullanın. Bu duruma sahipseniz, ne olursa olsun başınız belaya girer, çünkü ne yaparsanız yapın konteyner türleri arasında ileri ve geri taşıma yapacaksınız.


7

COW farkının yanı sıra, STL kapları çeşitli platformlarda çok daha yaygın olarak desteklenmektedir. Qt, çalışmanızı "ana akım" platformlarla sınırlandırırsanız yeterince taşınabilirdir, ancak STL diğer birçok daha belirsiz platformda da mevcuttur (örneğin, Texas Instruments DSP'leri).

STL tek bir şirket tarafından kontrol edilmekten ziyade standart olduğundan, genel olarak konuşursak, STL kodunu kolayca okuyabilen, anlayabilen ve değiştirebilen daha fazla programcı ve bunları desteklemek için daha fazla kaynak (kitaplar, çevrimiçi forumlar, konferanslar, vb.) bunu Qt. Bu sadece Qt'den sadece bu nedenle uzak durması gerektiği anlamına gelmez; sadece, diğer tüm şeyler eşit olduğunda, STL'yi varsayılan olarak ayarlamanız gerekir, ancak elbette her şey nadiren eşittir, bu yüzden en mantıklı olan kendi bağlamınıza karar vermeniz gerekir.

AlexKR'nin cevabı ile ilgili olarak: STL performansı sınırlar içinde garanti edilir, ancak belirli bir uygulama STL'lerini hızlandırmak için platforma bağlı detaylardan yararlanabilir . Bu anlamda, farklı platformlarda farklı sonuçlar alabilirsiniz, ancak hiçbir zaman açık garantiden (modulo hataları) daha yavaş olmayacaktır.


9
İlk noktanıza gelince: OP'nin zaten Qt kullanan ve bu nedenle zaten "ana akım" platformlarla sınırlı projelere atıfta bulunduğunu varsayıyorum. Birisinin sadece konteyner sınıfları için Qt gibi ağır bir kütüphaneyi çekmesi pek olası görünmüyor.
ThisSuitIsBlackNot

4

Beş sentim: Qt konteynerlerin farklı platformlarda benzer şekilde çalışması gerekiyor. STL kapları STL uygulamasına bağlıdır. Farklı performans sonuçları elde edebilirsiniz.

DÜZENLEME: STL'nin "daha yavaş" olduğunu söylemiyorum, ancak çeşitli uygulama ayrıntılarının etkilerine işaret ediyorum.
Kontrol edin bu sonra belki, ve bu .
Ve bu gerçek bir STL problemi değil. Açıkçası, performansta önemli bir fark varsa, kodda STL kullanan bir sorun vardır.


Uygulamadan bağımsız olarak STL kaplarının hepsi benzerdir. Bitişik bir bellek bloğunda olması gerektiğinden, sahne arkasında bir liste gibi bir vektör uygulayamazsınız. STL ayrıca genellikle tüm büyük platformlarda devasa boyutlara göre optimize edilmiştir.
Yacoby

1
STL'nin vaat ettiklerine sadık kalırsanız (nasıl uygulandığını varsaymak yerine) STL'li platformlar arasında hareket etmekte asla sorun yaşamazsınız. Qt ile aynı.
Michael Kohne

Bu, gerçeğin tam tersidir. STL kapları tüm platformlarda her zaman aynı şekilde çalışır; eğer yapmazlarsa, STL değildirler. Ancak QT, performansı sürümden sürüme büyük ölçüde değiştirir, bu nedenle QT4.8 yerine QT4.0 olan bir platformda bazı ciddi değişiklikler alabilirsiniz.
Alice

1
Çok farklı iki performans türünü karıştırıyorsunuz; algoritmik performans ve pratik hesaplama performansı. Tüm STL uygulamaları aynı algoritmik performansı garanti eder; vektörünüz bir öğeyi dizine eklemek için günlük (n) zaman alıyorsa, bu bir STL vektörü değildir. Bağlantılarınız, bu tartışmada anlamsız olan pratik hesaplama performansına işaret ediyor; QT algoritmalarını sürümler arasında değiştirir ve farklı platformlarda aynı C ++ farklı performans elde eder. Bunlar benim tecrübelerime göre, STL performansındaki farklılıklardan çok daha şekillendirilebilir.
Alice

3

Sanırım Qt. Ürününüzün her yerinde kullanıyorsanız, muhtemelen Qt kapları kullanmak mantıklıdır. Yalnızca UI bölümüne (örneğin) eklerseniz, C ++ standart kaplarını kullanmak daha iyi olabilir.


3

Ben STL mükemmel bir yazılım parçası olduğunu düşünüyorum ama bazı KDE veya Qt ile ilgili programlama yapmak eğer o zaman Qt gitmek için yol. Ayrıca kullandığınız derleyiciye bağlıdır, GCC STL oldukça iyi çalışır, ancak SUN Studio CC'yi kullanmanız gerekiyorsa, STL büyük olasılıkla derleyici STL değil deriden baş ağrısı getirecektir. Bu durumda derleyici başınızı incitir çünkü size sorunu kurtarmak için Qt kullanın. Sadece 2 sentim ...


3

QVector'da (bazen) büyük bir sınırlama vardır. Yalnızca int bayt bellek ayırabilir (sınırın eleman sayısı değil bayt cinsinden olduğuna dikkat edin). Bu, bir QVector ile ~ 2GB'den daha büyük bitişik bellek blokları ayırmaya çalışmanın çökmeye neden olacağı anlamına gelir. Bu, Qt 4 ve 5 ile olur. Std :: vector'un böyle bir sınırlaması yoktur.


0

Benim için STL kaplarıyla gitmenin ana nedeni, hafızayı çok büyük kaplarda yeniden kullanmak için özel bir ayırıcıya ihtiyacınız varsa. Diyelim ki 1000000 giriş (anahtar / değer çifti) saklayan bir QMap'iniz var. Qt olarak bu newne olursa olsun tam olarak 1000000 milyon tahsis ( çağrı) anlamına gelir . STL'de her zaman dahili olarak tüm bu belleği bir kerede tahsis eden ve harita dolduruldukça her bir girişe atayabileceğiniz özel bir ayırıcı oluşturabilirsiniz.

Tavsiyem, iş mantığında performans açısından kritik algoritmalar yazarken STL kapsayıcılarını kullanmak ve daha sonra sonuçlar UI denetimleriniz ve gerekirse formlarınız tarafından görüntülenmeye hazır olduğunda bunları tekrar Qt kaplarına dönüştürmektir.


Burada değil QTL'i savunmaya çalışan, ancak olabilir uzmanlaşmak QMapNode<K,V>şunlara ait K, Vkendi sağlamaktır operator new.
Marc Mutz - mmutz
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.