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::listya std::dequeda 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 dequeuç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::queuesadece 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::listve std::dequehem 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 dequebununla 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. dequeBellek 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, dequea 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, dequebir testte a kullanarak ve listdiğ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 listveya sarmanın dequeperformans 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 queuetemeldeki kapsayıcı ham kullanımına kıyasla a kullanmak performansı düşürmez. Daha önce de söylediğim gibi, queuetemiz, kullanımı kolay ve güvenli olduğu için ve gerçekten bir sorun profili ve testi haline gelirse, kullanın.