Sayısız cevap olduğu için kafanız karışabilir, ancak özetlemek gerekirse:
Bir std::queue
. Bunun nedeni basit: bir FIFO yapısıdır. FIFO istiyorsanız, bir std::queue
.
Niyetinizi başkalarına ve hatta kendinize açık hale getirir. A std::list
ya std::deque
da değil. Bir liste herhangi bir yere eklenebilir ve kaldırılabilir, ki bu bir FIFO yapısının yapması gereken şey değildir ve bir deque
uçtan bir ekleyip çıkarabilir, ki bu da bir FIFO yapısının yapamayacağı bir şeydir.
Bu nedenle bir queue
.
Şimdi, performansı sordun. İlk olarak, her zaman şu önemli kuralı hatırlayın: Önce iyi kod, sonra performans.
Bunun nedeni basit: Temizlik ve şıklıktan önce performans için çabalayan insanlar neredeyse her zaman en son bitiriyor. Kodları bir lapa haline gelir, çünkü ondan gerçekten hiçbir şey elde etmek için iyi olan her şeyi terk etmişlerdir.
Önce iyi, okunabilir kod yazarak, çoğunuz performans problemlerini kendiliğinden çözecektir. Ve daha sonra performansınızın yetersiz olduğunu fark ederseniz, artık güzel, temiz kodunuza bir profilleyici eklemek ve sorunun nerede olduğunu bulmak çok kolay.
Hepsi söylendi, std::queue
sadece bir adaptör. Güvenli arayüz sağlar, ancak içeride farklı bir konteyner kullanır. Bu temel kapsayıcıyı seçebilirsiniz ve bu büyük ölçüde esneklik sağlar.
Peki hangi temel kapsayıcıyı kullanmalısınız? Bunu biliyoruz std::list
ve std::deque
hem gerekli işlevleri sağlamak ( push_back()
, pop_front()
ve front()
), bu yüzden nasıl karar vereceğiz?
İlk olarak, bellek ayırmanın (ve ayırmanın) genellikle yapılacak hızlı bir şey olmadığını anlayın, çünkü bu, işletim sistemine gidip ondan bir şey yapmasını istemeyi içerir. A list
, her bir şey eklendiğinde bellek ayırmalı ve gittiğinde onu serbest bırakmalıdır.
deque
Öte yandan A , parçalar halinde tahsis eder. A'dan daha az sıklıkta ayıracaktır list
. Bunu bir liste olarak düşünün, ancak her bellek parçası birden fazla düğümü tutabilir. (Elbette, nasıl çalıştığını gerçekten öğrenmenizi öneririm .)
Yani tek başına deque
bununla daha iyi performans göstermelidir çünkü bellekle pek sık ilgilenmez. Sabit büyüklükteki verileri işlediğiniz gerçeğiyle karıştırıldığında, muhtemelen verilerden ilk geçişten sonra ayırmak zorunda kalmayacak, oysa bir liste sürekli olarak tahsis edecek ve serbest bırakacaktır.
Anlaşılması gereken ikinci bir şey de önbellek performansı . RAM'e çıkmak yavaştır, bu nedenle CPU gerçekten ihtiyaç duyduğunda, bir yığın belleği önbelleğe geri alarak bu zamandan en iyi şekilde yararlanır. deque
Bellek yığınlarında bir ayırma olduğu için, bu kapsayıcıdaki bir öğeye erişmenin CPU'nun kabın geri kalanını da geri getirmesine neden olması muhtemeldir. Şimdi deque
, veri önbellekte olduğu için başka erişim hızlı olacaktır.
Bu, verilerin teker teker tahsis edildiği bir listeden farklıdır. Bu, verilerin belleğin her yerine yayılabileceği ve önbellek performansının kötü olacağı anlamına gelir.
Bu nedenle, bunu göz önünde bulundurarak, deque
a daha iyi bir seçim olmalıdır. Bu nedenle, bir queue
. Tüm bunlarla birlikte, bu hala sadece (çok) eğitimli bir tahmin: Bu kodun profilini, deque
bir testte a kullanarak ve list
diğerinde gerçekten kesin olarak bilmek zorunda kalacaksın .
Ancak unutmayın: kodu temiz bir arayüzle çalıştırın, ardından performans konusunda endişelenin.
John, a list
veya sarmanın deque
performans düşüşüne neden olacağı endişesini dile getiriyor . Bir kez daha, kendisinin profilini çıkarmadan kesin olarak söyleyemeyiz, ancak derleyicinin yaptığı çağrıları satır içi yapması ihtimali vardır queue
. Yani, dediğinizde queue.push()
, gerçekten sadece queue.container.push_back()
işlev çağrısını tamamen atlayarak diyecektir .
Bir kez daha, bu yalnızca eğitimli bir tahmindir, ancak queue
temeldeki kapsayıcı ham kullanımına kıyasla a kullanmak performansı düşürmez. Daha önce de söylediğim gibi, queue
temiz, kullanımı kolay ve güvenli olduğu için ve gerçekten bir sorun profili ve testi haline gelirse, kullanın.