จะกำหนดขนาดเริ่มต้นของ std :: vector ได้อย่างไร?


130

ฉันมีvector<CustomClass*>และฉันใส่รายการจำนวนมากในเวกเตอร์และฉันต้องการการเข้าถึงที่รวดเร็วดังนั้นฉันจึงไม่ใช้รายการ จะกำหนดขนาดเริ่มต้นของเวกเตอร์ได้อย่างไร (ตัวอย่างเช่นเป็น 20,000 ตำแหน่งเพื่อหลีกเลี่ยงการคัดลอกเมื่อฉันแทรกใหม่)


1
มีตัวสร้างและสองฟังก์ชันสำหรับสิ่งนี้ในstd::vectorการอ้างอิงใด ๆขึ้นอยู่กับสิ่งที่เหมาะกับความต้องการของคุณมากกว่า
chris

1
คุณไม่สามารถหลีกเลี่ยงการคัดลอกได้เพียงแค่ตั้งค่าเริ่มต้น
juanchopanza

1
หลีกเลี่ยงสำเนาของ? การจัดเก็บพอยน์เตอร์มีน้ำหนักเบาในแง่ของต้นทุนในการคัดลอก
user7116


1
@ ดาเมียร์คุณหมายถึงstd::vectorชื่อเรื่องหรือเปล่า?
Robᵩ

คำตอบ:


180
std::vector<CustomClass *> whatever(20000);

หรือ:

std::vector<CustomClass *> whatever;
whatever.reserve(20000);

อดีตกำหนดขนาดจริงของอาร์เรย์นั่นคือทำให้เป็นเวกเตอร์ 20000 พอยน์เตอร์ หลังปล่อยให้เวกเตอร์ว่างเปล่า แต่สงวนพื้นที่ไว้สำหรับ 20000 พอยน์เตอร์ดังนั้นคุณสามารถแทรก (มากถึง) จำนวนมากได้โดยไม่ต้องจัดสรรใหม่

อย่างน้อยก็จากประสบการณ์ของฉันมันค่อนข้างผิดปกติสำหรับสิ่งเหล่านี้ที่จะสร้างความแตกต่างอย่างมากในด้านประสิทธิภาพ - แต่อาจส่งผลต่อความถูกต้องในบางสถานการณ์ โดยเฉพาะอย่างยิ่งตราบใดที่ไม่มีการจัดสรรใหม่เกิดขึ้นการทำซ้ำในเวกเตอร์จะได้รับการรับรองว่ายังคงถูกต้องและเมื่อคุณกำหนดขนาด / พื้นที่ที่จองไว้แล้วคุณจะรับประกันได้ว่าจะไม่มีการจัดสรรซ้ำตราบใดที่คุณไม่ t เพิ่มขนาดเกินกว่านั้น


ข้อใดต่อไปนี้จะมีประสิทธิภาพมากกว่าสำหรับการแทรก / ลบจำนวนมาก
ctor

3
@Loggie: ฉันสงสัยว่าจะมีประสิทธิภาพแตกต่างกัน ส่วนใหญ่จะเปลี่ยนวิธีการใช้งานของคุณ - โดยที่ก่อนหน้านี้คุณเพียงแค่พูดถึงตัวชี้ดังนั้นบางอย่างเช่นwhatever[10000] = somepointer;ที่push_backตัวชี้หลังต้องการให้คุณใช้ตัวชี้แต่ละตัวที่คุณเพิ่ม อย่างน้อยถ้าคุณคุ้นเคยvectorอย่างหลังก็น่าจะง่ายกว่าและเป็นธรรมชาติกว่า
Jerry Coffin

หากทราบขนาดของคอนเทนเนอร์ที่คัดลอกมาแล้วเหตุใดจึงไม่ใช้ขนาด (re) ที่มีประสิทธิภาพมากกว่าแล้วคัดลอกแทนที่จะเป็น push_back

1
@Cincinnatus: เนื่องจากมีการเรียกร้องreserveซึ่งจะจัดสรรขนาดหน่วยความจำไว้ล่วงหน้า ตามทฤษฎีแล้วการตั้งค่าขนาดอาจเร็วกว่าเล็กน้อยเนื่องจากจะหลีกเลี่ยงการเพิ่มขนาดปัจจุบันทุกครั้งที่คุณเพิ่มรายการ ในความเป็นจริงฉันสงสัยว่าคุณสามารถวัดได้ว่า
Jerry Coffin

1
จริงๆแล้วถ้าคุณกำลังทำสิ่งนี้บนเส้นทางที่ร้อนแรงและมีการเรียกรหัสเป็นจำนวนมากคุณสามารถให้คำแนะนำและประหยัดเวลาได้มาก
bayindirh

15

คุณต้องใช้ฟังก์ชันการสำรองเพื่อกำหนดขนาดที่จัดสรรเริ่มต้นหรือทำในตัวสร้างเริ่มต้น

vector<CustomClass *> content(20000);

หรือ

vector<CustomClass *> content;
...
content.reserve(20000);

เมื่อคุณจัดreserve()องค์ประกอบองค์ประกอบvectorจะจัดสรรพื้นที่เพียงพอสำหรับ (อย่างน้อย?) ที่หลายองค์ประกอบ องค์ประกอบไม่มีอยู่ในvectorแต่หน่วยความจำพร้อมใช้งาน จากนั้นอาจเร็วขึ้นpush_back()เนื่องจากหน่วยความจำได้รับการจัดสรรแล้ว


การจัดสรรขนาดสามารถระบุได้ในระหว่างการก่อสร้างโดยส่งผ่านอาร์กิวเมนต์อินทิกรัล (เช่นstd::vector<Custom Class*> content(100);)
adelbertc

@kstruct: ใช่ แต่อาจมีประสิทธิภาพน้อยลง - โดยปริมาณที่น้อยมาก
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.