เนื่องจากมีคำตอบมากมายคุณจึงอาจสับสน แต่สรุป:
ใช้ไฟล์std::queue
. เหตุผลง่ายๆก็คือโครงสร้าง FIFO คุณต้องการ FIFO คุณใช้ไฟล์std::queue
.
มันทำให้เจตนาของคุณชัดเจนสำหรับคนอื่นและแม้แต่ตัวคุณเอง A std::list
หรือstd::deque
ไม่ รายการสามารถแทรกและลบได้ทุกที่ซึ่งไม่ใช่สิ่งที่โครงสร้าง FIFO ควรทำและdeque
สามารถเพิ่มและลบจากปลายด้านใดด้านหนึ่งซึ่งเป็นสิ่งที่โครงสร้าง FIFO ไม่สามารถทำได้
นี่คือเหตุผลที่คุณควรใช้ไฟล์queue
.
ตอนนี้คุณถามเกี่ยวกับประสิทธิภาพ ประการแรกจำกฎง่ายๆนี้ไว้เสมอ: รหัสที่ดีก่อนประสิทธิภาพสุดท้าย
เหตุผลง่ายๆก็คือคนที่มุ่งมั่นเพื่อประสิทธิภาพก่อนที่ความสะอาดและความสง่างามมักจะเสร็จสิ้นเป็นอันดับสุดท้าย รหัสของพวกเขากลายเป็นเรื่องเหลวไหลเพราะพวกเขาละทิ้งทุกสิ่งที่ดีเพื่อที่จะไม่ได้อะไรจากมัน
การเขียนโค้ดที่ดีและอ่านได้ก่อนอื่นปัญหาด้านประสิทธิภาพส่วนใหญ่ของคุณจะคลี่คลายเอง และหากในภายหลังคุณพบว่าประสิทธิภาพของคุณขาดหายไปตอนนี้คุณสามารถเพิ่ม profiler ลงในโค้ดที่ดีและสะอาดของคุณได้อย่างง่ายดายและค้นหาว่าปัญหาอยู่ที่ใด
ที่กล่าวมาทั้งหมดstd::queue
เป็นเพียงอะแดปเตอร์เท่านั้น มีอินเทอร์เฟซที่ปลอดภัย แต่ใช้คอนเทนเนอร์อื่นที่อยู่ด้านใน คุณสามารถเลือกคอนเทนเนอร์พื้นฐานนี้และช่วยให้มีความยืดหยุ่นได้ดี
คุณควรใช้คอนเทนเนอร์ใด เรารู้ว่าstd::list
และstd::deque
ทั้งสองให้ฟังก์ชั่นที่จำเป็น ( push_back()
, pop_front()
และfront()
) ดังนั้นวิธีที่เราจะตัดสินใจ?
ก่อนอื่นให้ทำความเข้าใจว่าการจัดสรรหน่วยความจำ (และการจัดสรร) ไม่ใช่สิ่งที่ต้องทำโดยทั่วไปเนื่องจากเกี่ยวข้องกับการออกไปที่ระบบปฏิบัติการและขอให้ทำอะไรบางอย่าง A list
ต้องจัดสรรหน่วยความจำทุกครั้งที่มีการเพิ่มบางสิ่งและยกเลิกการจัดสรรหน่วยความจำเมื่อมันหายไป
A deque
ในทางกลับกันจัดสรรเป็นชิ้น ๆ จะจัดสรรน้อยกว่า a list
. คิดว่ามันเป็นรายการ แต่แต่ละหน่วยความจำสามารถเก็บได้หลายโหนด (แน่นอนฉันขอแนะนำให้คุณเรียนรู้วิธีการทำงานจริงๆ)
ดังนั้นด้วยสิ่งนั้นเพียงอย่างเดียวdeque
ควรทำงานได้ดีกว่าเพราะมันไม่ได้จัดการกับหน่วยความจำบ่อยเท่า เมื่อผสมกับความจริงที่ว่าคุณกำลังจัดการข้อมูลที่มีขนาดคงที่อาจไม่จำเป็นต้องจัดสรรหลังจากการส่งผ่านข้อมูลครั้งแรกในขณะที่รายการจะถูกจัดสรรและจัดสรรอย่างต่อเนื่อง
สิ่งที่สองที่จะเข้าใจได้ประสิทธิภาพแคช การออกไปที่ RAM นั้นช้าดังนั้นเมื่อจำเป็นต้องใช้ CPU จริงๆมันจะทำให้ดีที่สุดในช่วงเวลานี้โดยการดึงหน่วยความจำกลับไปในแคช เนื่องจากมีการdeque
จัดสรรในหน่วยความจำจึงมีแนวโน้มว่าการเข้าถึงองค์ประกอบในคอนเทนเนอร์นี้จะทำให้ CPU นำส่วนที่เหลือของคอนเทนเนอร์กลับมาด้วย ตอนนี้การเข้าถึงเพิ่มเติมdeque
จะเป็นไปอย่างรวดเร็วเนื่องจากข้อมูลอยู่ในแคช
ซึ่งแตกต่างจากรายการที่ข้อมูลจะถูกจัดสรรทีละรายการ ซึ่งหมายความว่าข้อมูลอาจกระจายออกไปทั่วทุกที่ในหน่วยความจำและประสิทธิภาพของแคชจะไม่ดี
ดังนั้นเมื่อพิจารณาแล้วdeque
ควรเป็นทางเลือกที่ดีกว่า ด้วยเหตุนี้จึงเป็นคอนเทนเนอร์เริ่มต้นเมื่อใช้ไฟล์queue
. ที่กล่าวมาทั้งหมดนี้ยังคงเป็นเพียงการคาดเดาที่มีการศึกษา (มาก): คุณจะต้องกำหนดโปรไฟล์รหัสนี้โดยใช้การdeque
ทดสอบในครั้งเดียวและlist
อีกรายการหนึ่งเพื่อให้ทราบอย่างแน่นอน
แต่อย่าลืมว่า: รับโค้ดที่ทำงานร่วมกับอินเทอร์เฟซที่สะอาดหมดจดแล้วกังวลเรื่องประสิทธิภาพ
จอห์นทำให้เกิดความกังวลว่าการห่อlist
หรือdeque
จะทำให้ประสิทธิภาพลดลง อีกครั้งเขาหรือฉันไม่สามารถพูดได้อย่างแน่นอนโดยไม่ต้องทำโปรไฟล์ด้วยตัวเอง แต่มีโอกาสที่คอมไพเลอร์จะอินไลน์การเรียกที่queue
ทำให้ นั่นคือเมื่อคุณพูดqueue.push()
มันจะพูดจริงๆqueue.container.push_back()
โดยข้ามการเรียกฟังก์ชันไปโดยสิ้นเชิง
อีกครั้งนี่เป็นเพียงการคาดเดาที่มีการศึกษา แต่การใช้queue
จะไม่ลดประสิทธิภาพเมื่อเทียบกับการใช้คอนเทนเนอร์ที่อยู่เบื้องหลัง อย่างที่ฉันเคยพูดไปแล้วให้ใช้queue
เพราะมันสะอาดใช้งานง่ายและปลอดภัยและถ้ามันกลายเป็นโปรไฟล์และการทดสอบที่มีปัญหาจริงๆ