ในหลักสูตร C ++ เราไม่แนะนำให้ใช้อาร์เรย์ C ++ ในโครงการใหม่อีกต่อไป เท่าที่ฉันรู้ Stroustroup ตัวเองไม่แนะนำให้ใช้อาร์เรย์ แต่มีความแตกต่างด้านประสิทธิภาพที่สำคัญหรือไม่
int main(int argc, const std::vector<string>& argv)
ในหลักสูตร C ++ เราไม่แนะนำให้ใช้อาร์เรย์ C ++ ในโครงการใหม่อีกต่อไป เท่าที่ฉันรู้ Stroustroup ตัวเองไม่แนะนำให้ใช้อาร์เรย์ แต่มีความแตกต่างด้านประสิทธิภาพที่สำคัญหรือไม่
int main(int argc, const std::vector<string>& argv)
คำตอบ:
new
ควรหลีกเลี่ยงการใช้ C ++ กับ(นั่นคือการใช้อาร์เรย์แบบไดนามิก) มีปัญหาที่คุณต้องติดตามขนาดและคุณต้องลบออกด้วยตนเองและทำความสะอาดทุกประเภท
การใช้อาร์เรย์บนสแต็กก็ไม่ได้รับการสนับสนุนเนื่องจากคุณไม่มีการตรวจสอบช่วงและการผ่านอาร์เรย์ไปรอบ ๆ จะสูญเสียข้อมูลใด ๆ เกี่ยวกับขนาดของมัน (การแปลงอาร์เรย์เป็นตัวชี้) คุณควรใช้boost::array
ในกรณีนั้นซึ่งจะล้อมอาร์เรย์ C ++ ในคลาสขนาดเล็กและจัดเตรียมsize
ฟังก์ชันและตัววนซ้ำเพื่อวนซ้ำ
ตอนนี้std :: vector เทียบกับอาร์เรย์ C ++ ดั้งเดิม (นำมาจากอินเทอร์เน็ต):
// Comparison of assembly code generated for basic indexing, dereferencing,
// and increment operations on vectors and arrays/pointers.
// Assembly code was generated by gcc 4.1.0 invoked with g++ -O3 -S on a
// x86_64-suse-linux machine.
#include <vector>
struct S
{
int padding;
std::vector<int> v;
int * p;
std::vector<int>::iterator i;
};
int pointer_index (S & s) { return s.p[3]; }
// movq 32(%rdi), %rax
// movl 12(%rax), %eax
// ret
int vector_index (S & s) { return s.v[3]; }
// movq 8(%rdi), %rax
// movl 12(%rax), %eax
// ret
// Conclusion: Indexing a vector is the same damn thing as indexing a pointer.
int pointer_deref (S & s) { return *s.p; }
// movq 32(%rdi), %rax
// movl (%rax), %eax
// ret
int iterator_deref (S & s) { return *s.i; }
// movq 40(%rdi), %rax
// movl (%rax), %eax
// ret
// Conclusion: Dereferencing a vector iterator is the same damn thing
// as dereferencing a pointer.
void pointer_increment (S & s) { ++s.p; }
// addq $4, 32(%rdi)
// ret
void iterator_increment (S & s) { ++s.i; }
// addq $4, 40(%rdi)
// ret
// Conclusion: Incrementing a vector iterator is the same damn thing as
// incrementing a pointer.
หมายเหตุ: หากคุณจัดสรรอาร์เรย์ด้วยnew
และจัดสรรวัตถุที่ไม่ใช่คลาส (เช่นธรรมดาint
) หรือคลาสที่ไม่มีตัวกำหนดที่ผู้ใช้กำหนดและคุณไม่ต้องการให้องค์ประกอบเริ่มต้นในตอนแรกการใช้new
อาร์เรย์ที่จัดสรรแล้วจะมีข้อดีด้านประสิทธิภาพเนื่องจากstd::vector
เริ่มองค์ประกอบทั้งหมด ค่าเริ่มต้น (0 สำหรับ int ตัวอย่างเช่น) ในการก่อสร้าง (เครดิตถึง @bernie สำหรับการเตือนฉัน)
โปรดจำไว้ว่า:
"โปรแกรมเมอร์เสียเวลาจำนวนมากที่คิดหรือกังวลเกี่ยวกับความเร็วของส่วนที่ไม่สำคัญของโปรแกรมและความพยายามเหล่านี้อย่างมีประสิทธิภาพมีผลกระทบเชิงลบอย่างมากเมื่อพิจารณาการดีบั๊กและการบำรุงรักษาเราควรลืมประสิทธิภาพเล็กน้อย 97% ของเวลา: การปรับให้เหมาะสมก่อนกำหนดเป็นรากฐานของความชั่วร้ายทั้งหมดแต่เราไม่ควรปล่อยให้โอกาสของเราผ่านไปในช่วงวิกฤตที่ 3% "
(ขอบคุณการเปลี่ยนแปลงสำหรับใบเสนอราคาเต็ม)
อย่าใช้อาร์เรย์ C แทนเวกเตอร์ (หรืออะไรก็ตาม) เพียงเพราะคุณเชื่อว่ามันเร็วกว่าที่ควรจะเป็นระดับที่ต่ำกว่า คุณจะผิด
ใช้โดยเวกเตอร์เริ่มต้น (หรือภาชนะที่ปลอดภัยที่ปรับให้เหมาะกับความต้องการของคุณ) และถ้าผู้สร้างโปรไฟล์ของคุณบอกว่ามันเป็นปัญหาดูว่าคุณสามารถปรับให้เหมาะสมได้หรือไม่โดยใช้อัลกอริทึมที่ดีกว่าหรือเปลี่ยนคอนเทนเนอร์
สิ่งนี้กล่าวว่าเราสามารถกลับไปที่คำถามเดิม
คลาสอาเรย์ C ++ นั้นมีพฤติกรรมที่ดีกว่าอาเรย์ C ระดับต่ำเพราะพวกเขารู้มากเกี่ยวกับตัวเองและสามารถตอบคำถามที่อาร์เรย์ C ไม่สามารถทำได้ พวกเขาสามารถทำความสะอาดหลังจากที่ตัวเอง และที่สำคัญพวกเขามักจะเขียนโดยใช้เทมเพลตและ / หรือการทำอินไลน์ซึ่งหมายความว่าสิ่งที่ปรากฏในโค้ดจำนวนมากในการดีบั๊กจะแก้ไขเป็นโค้ดเพียงเล็กน้อยหรือไม่มีเลยที่สร้างขึ้นในรีลีสการสร้าง
สรุปแล้วมันมีสองประเภท:
การใช้ตัวชี้ไปยังอาร์เรย์ malloc-ed / new-ed จะเร็วที่สุดเท่ารุ่น std :: vector และปลอดภัยน้อยกว่ามาก (ดูบทความของ litb )
ดังนั้นใช้ std :: vector
การใช้อาร์เรย์คงที่จะดีที่สุด:
ดังนั้นใช้มาตรฐาน :: อาร์เรย์
บางครั้งใช้vector
แทนของบัฟเฟอร์ดิบเกิดค่าใช้จ่ายที่สามารถมองเห็นได้เพราะvector
จะเริ่มต้นบัฟเฟอร์ที่ก่อสร้างในขณะที่รหัสแทนที่ไม่ได้เป็นข้อสังเกตBernieโดยในของเขาคำตอบ
หากเป็นกรณีนี้คุณสามารถจัดการได้โดยใช้ a unique_ptr
แทนvector
หรือถ้ากรณีไม่ได้อยู่ใน codeline ของคุณให้เขียนคลาสbuffer_owner
ที่จะเป็นเจ้าของหน่วยความจำนั้นและให้คุณเข้าถึงได้ง่ายและปลอดภัยรวมถึง โบนัสเช่นการปรับขนาด (โดยใช้realloc
?) หรืออะไรก็ตามที่คุณต้องการ
เวกเตอร์เป็นอาร์เรย์ภายใต้ประทุน ประสิทธิภาพการทำงานเหมือนกัน
ที่เดียวที่คุณสามารถพบปัญหาเรื่องประสิทธิภาพไม่ได้กำหนดขนาดของเวกเตอร์อย่างถูกต้องตั้งแต่แรก
เมื่อเวกเตอร์เติมมันจะปรับขนาดตัวเองและนั่นอาจหมายถึงการจัดสรรอาร์เรย์ใหม่ตามด้วยตัวสร้างสำเนา n ตามด้วยการเรียก n destructor ประมาณ n ตามด้วยการลบอาร์เรย์
หากการก่อสร้าง / การทำลายล้างของคุณมีราคาแพงคุณจะยิ่งดีกว่าที่จะทำให้เวกเตอร์มีขนาดเริ่มต้นที่ถูกต้อง
มีวิธีง่ายๆในการสาธิตสิ่งนี้ สร้างคลาสง่าย ๆ ที่แสดงเมื่อมันถูกสร้าง / ทำลาย / คัดลอก / มอบหมาย สร้างเวกเตอร์ของสิ่งเหล่านี้และเริ่มผลักพวกมันที่ด้านหลังของเวกเตอร์ เมื่อเวกเตอร์เติมจะมีกิจกรรมเรียงซ้อนกันเมื่อเวกเตอร์ปรับขนาด จากนั้นลองอีกครั้งโดยใช้เวกเตอร์ที่มีขนาดเท่ากับจำนวนองค์ประกอบที่คาดหวัง คุณจะเห็นความแตกต่าง
std::vector
ฟังดูไม่ได้มาตรฐานหรือเปล่า? ฉันเชื่อว่ามาตรฐานกำหนดให้ต้องvector::push_back
มีการตัดจำหน่ายความซับซ้อนคงที่และการเพิ่มความจุ 1 โดยแต่ละรายการpush_back
จะเป็นความซับซ้อน n ^ 2 หลังจากที่คุณทำการ reallocs - สันนิษฐานว่าการเพิ่มความจุแบบเอ็กซ์โปเนนเชียลบางอย่างเกิดขึ้นpush_back
และinsert
ความล้มเหลวที่reserve
จะนำไปสู่การเพิ่มขึ้นอย่างต่อเนื่องของปัจจัยในการคัดลอกเนื้อหาเวกเตอร์ ปัจจัยการเจริญเติบโต 1.5 ชี้แจงเวกเตอร์จะหมายถึง ~ 3x reserve()
เป็นหลายสำเนาถ้าคุณล้มเหลวในการ
เพื่อตอบสนองต่อสิ่งที่Mehrdadกล่าวว่า:
อย่างไรก็ตามอาจมีบางกรณีที่คุณยังต้องการอาร์เรย์ เมื่อเชื่อมต่อกับรหัสระดับต่ำ (เช่นชุดประกอบ) หรือไลบรารีเก่าที่ต้องใช้อาร์เรย์คุณอาจไม่สามารถใช้เวกเตอร์ได้
ไม่จริงเลย เวกเตอร์ย่อยสลายอย่างเป็นอาร์เรย์ / พอยน์เตอร์ถ้าคุณใช้:
vector<double> vector;
vector.push_back(42);
double *array = &(*vector.begin());
// pass the array to whatever low-level code you have
สิ่งนี้ใช้ได้กับการใช้งาน STL ที่สำคัญทั้งหมด ในมาตรฐานถัดไปมันจะต้องทำงาน (แม้ว่ามันจะไม่เป็นไรวันนี้)
&v[n] == &v[0] + n
ถูกต้องให้n
อยู่ในช่วงขนาด ย่อหน้าที่มีคำสั่งนี้ไม่ได้เปลี่ยนแปลงด้วย C ++ 11
คุณมีเหตุผลน้อยลงที่จะใช้อาร์เรย์ธรรมดาใน C ++ 11
มีอาร์เรย์ 3 แบบในธรรมชาติตั้งแต่เร็วที่สุดไปจนถึงช้าที่สุดขึ้นอยู่กับคุณสมบัติที่มี (แน่นอนว่าคุณภาพของการติดตั้งสามารถทำให้สิ่งต่าง ๆ รวดเร็วยิ่งขึ้นสำหรับกรณีที่ 3 ในรายการ):
std::array<T, N>
dynarray
อยู่ใน C ++ TS หลังจาก C ++ 14 ใน C มี VLAstd::vector<T>
สำหรับ1.อาร์เรย์คงที่ธรรมดาที่มีจำนวนองค์ประกอบคงที่ให้ใช้std::array<T, N>
ใน C ++ 11
สำหรับ2อาร์เรย์ขนาดคงที่ที่ระบุที่รันไทม์ แต่นั่นจะไม่เปลี่ยนขนาดของมันมีการสนทนาใน C ++ 14 แต่มันถูกย้ายไปยังข้อกำหนดทางเทคนิคและทำจาก C ++ 14 ในที่สุด
สำหรับ3. มักจะถามสำหรับหน่วยความจำในกองstd::vector<T>
สิ่งนี้อาจมีผลกระทบด้านประสิทธิภาพแม้ว่าคุณสามารถใช้std::vector<T, MyAlloc<T>>
เพื่อปรับปรุงสถานการณ์ด้วยตัวจัดสรรที่กำหนดเอง ประโยชน์ที่ได้รับเมื่อเทียบกับT mytype[] = new MyType[n];
คือคุณสามารถปรับขนาดได้และจะไม่สลายตัวไปยังตัวชี้เหมือนกับที่อาร์เรย์ธรรมดาทำ
ใช้ไลบรารีมาตรฐานประเภทที่กล่าวถึงเพื่อหลีกเลี่ยง อาร์เรย์ที่สลายตัวไปเป็นพอยน์เตอร์ คุณจะประหยัดเวลาในการดีบั๊กและประสิทธิภาพการทำงานจะเหมือนกับในอาร์เรย์ธรรมดาถ้าคุณใช้ฟีเจอร์ชุดเดียวกัน
ไปกับ STL ไม่มีโทษประสิทธิภาพ อัลกอริทึมมีประสิทธิภาพมากและทำงานได้ดีในการจัดการรายละเอียดชนิดต่าง ๆ ที่พวกเราส่วนใหญ่จะไม่คิด
STL เป็นไลบรารีที่ปรับให้เหมาะสมอย่างมาก ที่จริงแล้วยังแนะนำให้ใช้ STL ในเกมที่อาจต้องการประสิทธิภาพสูง อาร์เรย์มีข้อผิดพลาดมากเกินไปที่จะใช้ในงานประจำวัน คอมไพเลอร์ในวันนี้ยังฉลาดและสามารถสร้างโค้ดที่ยอดเยี่ยมด้วย STL หากคุณรู้ว่าคุณกำลังทำอะไร STL จะสามารถมอบประสิทธิภาพที่จำเป็นได้ ตัวอย่างเช่นการกำหนดค่าเริ่มต้นเวกเตอร์เป็นขนาดที่ต้องการ (ถ้าคุณรู้ตั้งแต่เริ่มต้น) คุณสามารถบรรลุประสิทธิภาพอาร์เรย์ได้ อย่างไรก็ตามอาจมีบางกรณีที่คุณยังต้องการอาร์เรย์ เมื่อเชื่อมต่อกับรหัสระดับต่ำ (เช่นชุดประกอบ) หรือไลบรารีเก่าที่ต้องใช้อาร์เรย์คุณอาจไม่สามารถใช้เวกเตอร์ได้
vec.data()
สำหรับข้อมูลและvec.size()
ขนาด มันง่ายมาก
เกี่ยวกับผลงานของ Duli
บทสรุปคืออาร์เรย์ของจำนวนเต็มเร็วกว่าเวกเตอร์ของจำนวนเต็ม (5 เท่าในตัวอย่างของฉัน) อย่างไรก็ตามอาร์เรย์และเวกเตอร์มีการจัดเรียงความเร็วเดียวกันสำหรับข้อมูลที่ซับซ้อนมากขึ้น / ไม่จัดชิด
หากคุณคอมไพล์ซอฟต์แวร์ในโหมดดีบั๊กคอมไพเลอร์จำนวนมากจะไม่อินไลน์ฟังก์ชั่นการเข้าถึงของเวกเตอร์ สิ่งนี้จะทำให้การใช้เวกเตอร์ stl ช้าลงมากในสถานการณ์ที่ประสิทธิภาพเป็นปัญหา นอกจากนี้ยังจะทำให้รหัสง่ายต่อการตรวจแก้จุดบกพร่องเนื่องจากคุณสามารถดูในการดีบักจำนวนหน่วยความจำที่ถูกปันส่วน
ในโหมดออพติไมซ์ผมคาดว่า stl vector จะเข้าหาประสิทธิภาพของอาเรย์ นี่คือเนื่องจากวิธีการเวกเตอร์จำนวนมากอยู่ในขณะนี้
มีผลกระทบต่อประสิทธิภาพอย่างแน่นอนในการใช้std::vector
vs a raw array เมื่อคุณต้องการบัฟเฟอร์ที่ไม่ได้กำหนดค่าเริ่มต้น (เช่นใช้เป็นปลายทางสำหรับmemcpy()
) std::vector
จะเริ่มต้นทุกองค์ประกอบของการใช้ constructor เริ่มต้น อาร์เรย์ดิบจะไม่
C ++ ข้อมูลจำเพาะสำหรับstd:vector
ตัวสร้างการcount
โต้แย้ง (มันเป็นรูปแบบที่สาม) ฯ :
`สร้างคอนเทนเนอร์ใหม่จากแหล่งข้อมูลที่หลากหลายโดยเลือกใช้การจัดสรรตัวจัดสรรของผู้ใช้
3) สร้างคอนเทนเนอร์ด้วยอินสแตนซ์ที่นับจำนวนเริ่มต้นของ T ไม่มีการทำสำเนา
ความซับซ้อน
2-3) การนับเชิงเส้น
อาเรย์ดิบไม่ต้องเสียค่าใช้จ่ายในการเริ่มต้นนี้
ดูเพิ่มเติมฉันจะหลีกเลี่ยง std :: vector <> เพื่อเริ่มต้นองค์ประกอบทั้งหมดได้อย่างไร
ความแตกต่างของประสิทธิภาพระหว่างทั้งสองนั้นขึ้นอยู่กับการใช้งานอย่างมาก - ถ้าคุณเปรียบเทียบ std :: vector ที่นำไปใช้อย่างไม่เหมาะสมกับการใช้งานอาร์เรย์ที่เหมาะสมอาร์เรย์จะชนะ แต่หมุนไปรอบ ๆ และเวกเตอร์จะชนะ ...
ตราบใดที่คุณเปรียบเทียบแอปเปิ้ลกับแอปเปิ้ล (ทั้งอาร์เรย์และเวกเตอร์มีจำนวนองค์ประกอบคงที่หรือทั้งสองได้รับการปรับขนาดแบบไดนามิก) ฉันจะคิดว่าความแตกต่างของประสิทธิภาพนั้นไม่มีความสำคัญตราบใดที่คุณปฏิบัติตาม อย่าลืมว่าการใช้คอนเทนเนอร์ C ++ มาตรฐานยังช่วยให้คุณสามารถใช้อัลกอริทึมก่อนรีดที่เป็นส่วนหนึ่งของไลบรารี C ++ มาตรฐานและส่วนใหญ่จะมีประสิทธิภาพที่ดีกว่าการใช้งานเฉลี่ยของอัลกอริทึมเดียวกันกับที่คุณสร้างขึ้นเอง .
ที่กล่าวว่า IMHO เวกเตอร์ชนะในสถานการณ์การดีบักด้วย debug STL เนื่องจากการใช้งาน STL ส่วนใหญ่ที่มีโหมดการดีบักที่เหมาะสมอย่างน้อยสามารถเน้น / cathc ข้อผิดพลาดทั่วไปที่ทำโดยคนเมื่อทำงานกับภาชนะมาตรฐาน
โอ้และอย่าลืมว่าอาร์เรย์และเวกเตอร์ใช้เค้าโครงหน่วยความจำเดียวกันเพื่อให้คุณสามารถใช้เวกเตอร์เพื่อส่งผ่านข้อมูลไปยังรหัส C หรือ C ++ แบบดั้งเดิมที่คาดว่าอาร์เรย์พื้นฐาน โปรดทราบว่าการเดิมพันส่วนใหญ่จะปิดในสถานการณ์นั้นและคุณกำลังจัดการกับหน่วยความจำดิบอีกครั้ง
std::deque
อาจใช้
หากคุณไม่จำเป็นต้องปรับขนาดแบบไดนามิกคุณมีหน่วยความจำโอเวอร์เฮดของการบันทึกความจุ (หนึ่งพอยน์เตอร์ / size_t) แค่นั้นแหละ.
อาจมีกรณีขอบที่คุณมีการเข้าถึงแบบเวกเตอร์ภายในฟังก์ชั่นแบบอินไลน์ภายในฟังก์ชั่นแบบอินไลน์ซึ่งคุณได้ไปเกินกว่าสิ่งที่คอมไพเลอร์จะแบบอินไลน์และมันจะบังคับให้เรียกฟังก์ชั่น ที่จะหายากเพื่อให้เป็นไปไม่คุ้มค่ากังวลเกี่ยวกับ - โดยทั่วไปผมจะเห็นด้วยกับlitb
ฉันประหลาดใจที่ไม่มีใครพูดถึงเรื่องนี้ - ไม่ต้องกังวลเกี่ยวกับประสิทธิภาพจนกว่าจะได้รับการพิสูจน์แล้วว่าเป็นปัญหาและเป็นมาตรฐาน
ฉันขอยืนยันว่าข้อกังวลหลักไม่ใช่ประสิทธิภาพ แต่ความปลอดภัย คุณสามารถทำข้อผิดพลาดได้มากมายด้วยอาร์เรย์ (ลองพิจารณาการปรับขนาดตัวอย่าง) ซึ่งเวกเตอร์จะช่วยคุณเจ็บปวดได้มาก
เวกเตอร์ใช้หน่วยความจำน้อยกว่าอาร์เรย์เล็กน้อยเนื่องจากมีขนาดของอาร์เรย์ พวกเขายังเพิ่มขนาดฮาร์ดดิสก์ของโปรแกรมและอาจเป็นรอยเท้าหน่วยความจำของโปรแกรม เพิ่มขึ้นเหล่านี้มีขนาดเล็ก แต่อาจสำคัญถ้าคุณทำงานกับระบบฝังตัว แม้ว่าสถานที่ส่วนใหญ่ที่ความแตกต่างเหล่านี้มีความสำคัญคือสถานที่ที่คุณจะใช้ C แทน C ++
การทดสอบอย่างง่ายต่อไปนี้:
คำอธิบายการทดสอบประสิทธิภาพของ C ++ Array vs Vector
ขัดแย้งกับข้อสรุปจาก "การเปรียบเทียบรหัสแอสเซมบลีที่สร้างขึ้นสำหรับการทำดัชนีขั้นพื้นฐานการยกเลิกการลงทะเบียนและการดำเนินการเพิ่มในเวกเตอร์และอาร์เรย์ / พอยน์เตอร์"
จะต้องมีความแตกต่างระหว่างอาร์เรย์และเวกเตอร์ การทดสอบบอกว่า ... แค่ลองใช้รหัสก็มี ...
บางครั้งอาร์เรย์ดีกว่าเวกเตอร์ หากคุณจัดการชุดวัตถุที่มีความยาวคงที่อยู่เสมออาร์เรย์จะดีกว่า พิจารณาตัวอย่างโค้ดต่อไปนี้:
int main() {
int v[3];
v[0]=1; v[1]=2;v[2]=3;
int sum;
int starttime=time(NULL);
cout << starttime << endl;
for (int i=0;i<50000;i++)
for (int j=0;j<10000;j++) {
X x(v);
sum+=x.first();
}
int endtime=time(NULL);
cout << endtime << endl;
cout << endtime - starttime << endl;
}
โดยที่ vector version ของ X คือ
class X {
vector<int> vec;
public:
X(const vector<int>& v) {vec = v;}
int first() { return vec[0];}
};
และรุ่นอาร์เรย์ของ X คือ:
class X {
int f[3];
public:
X(int a[]) {f[0]=a[0]; f[1]=a[1];f[2]=a[2];}
int first() { return f[0];}
};
อาเรย์เวอร์ชันจะเป็น main () จะเร็วขึ้นเนื่องจากเราหลีกเลี่ยงค่าใช้จ่าย "ใหม่" ทุกครั้งในลูปด้านใน
(รหัสนี้ถูกโพสต์ไปยัง comp.lang.c ++ โดยฉัน)
หากคุณใช้เวกเตอร์เพื่อแสดงพฤติกรรมหลายมิติจะมีการแสดงที่ยอดเยี่ยม
เวกเตอร์ 2 มิติ + เป็นสาเหตุของการทำงานหรือไม่
สรุปสาระสำคัญคือมีค่าใช้จ่ายเล็กน้อยในแต่ละเวกเตอร์ย่อยที่มีข้อมูลขนาดและไม่จำเป็นต้องเป็นอนุกรมของข้อมูล (เช่นเดียวกับที่มีอาร์เรย์ c หลายมิติ) การขาดการทำให้เป็นอันดับอาจทำให้มีโอกาสในการเพิ่มประสิทธิภาพมากขึ้น หากคุณกำลังทำอาร์เรย์หลายมิติคุณควรขยาย std :: vector และหมุนฟังก์ชัน get / set / resize bits ของคุณเอง
สมมติว่าอาเรย์ที่มีความยาวคงที่ (เช่นint* v = new int[1000];
vs std::vector<int> v(1000);
กับขนาดของv
การคงที่ไว้ที่ 1,000) การพิจารณาประสิทธิภาพเพียงอย่างเดียวที่สำคัญจริงๆ (หรืออย่างน้อยสำคัญกับฉันเมื่อฉันอยู่ในภาวะที่กลืนไม่เข้าคายไม่ออกที่คล้ายกัน) คือความเร็วในการเข้าถึง ธาตุ. ฉันค้นหารหัสเวกเตอร์ของ STL และนี่คือสิ่งที่ฉันพบ:
const_reference
operator[](size_type __n) const
{ return *(this->_M_impl._M_start + __n); }
ฟังก์ชั่นนี้จะถูกคอมไพเลอร์อย่างแน่นอนที่สุด ดังนั้นตราบใดที่สิ่งเดียวที่คุณวางแผนที่จะทำv
คือเข้าถึงองค์ประกอบด้วยoperator[]
ดูเหมือนว่าไม่ควรมีความแตกต่างในประสิทธิภาพการทำงาน