วิธีที่เร็วที่สุดในการรีเซ็ตค่าทุกค่าเป็นstd::vector<int>
0 และรักษาขนาดเริ่มต้นของเวกเตอร์คืออะไร
สำหรับลูปที่มีโอเปอเรเตอร์ [] หรือไม่
วิธีที่เร็วที่สุดในการรีเซ็ตค่าทุกค่าเป็นstd::vector<int>
0 และรักษาขนาดเริ่มต้นของเวกเตอร์คืออะไร
สำหรับลูปที่มีโอเปอเรเตอร์ [] หรือไม่
คำตอบ:
std::fill(v.begin(), v.end(), 0);
v = std::vector<int>(vec_size,0)
) ดูเหมือนว่าจะเร็วกว่าfill
บนเครื่องของฉันเล็กน้อย
assign
วิธีนี้เป็นวิธีสำนวนมากที่สุดของการทำมันสำนวนมากกว่าการใช้
เช่นเคยเมื่อคุณถามเกี่ยวกับเร็วที่สุด: วัด! การใช้วิธีการด้านบน (สำหรับ Mac โดยใช้เสียงดังกราว):
Method | executable size | Time Taken (in sec) |
| -O0 | -O3 | -O0 | -O3 |
------------|---------|---------|-----------|----------|
1. memset | 17 kB | 8.6 kB | 0.125 | 0.124 |
2. fill | 19 kB | 8.6 kB | 13.4 | 0.124 |
3. manual | 19 kB | 8.6 kB | 14.5 | 0.124 |
4. assign | 24 kB | 9.0 kB | 1.9 | 0.591 |
ใช้การทำซ้ำ 100000 ครั้งบนเวกเตอร์ที่มี 10,000 รายการ
แก้ไข:หาก changeing ตัวเลขนี้มีเหตุผลการเปลี่ยนแปลงครั้งส่งผลให้คุณสามารถมีบางความเชื่อมั่น (ไม่ดีเท่าที่ตรวจสอบรหัสการประกอบขั้นสุดท้าย) ที่มาตรฐานเทียมยังไม่ได้รับการปรับให้ออกไปอย่างสิ้นเชิง แน่นอนมันเป็นสิ่งที่ดีที่สุดที่จะ messing ประสิทธิภาพภายใต้เงื่อนไขจริง สิ้นสุดการแก้ไข
สำหรับการอ้างอิงรหัสที่ใช้:
#include <vector>
#define TEST_METHOD 1
const size_t TEST_ITERATIONS = 100000;
const size_t TEST_ARRAY_SIZE = 10000;
int main(int argc, char** argv) {
std::vector<int> v(TEST_ARRAY_SIZE, 0);
for(size_t i = 0; i < TEST_ITERATIONS; ++i) {
#if TEST_METHOD == 1
memset(&v[0], 0, v.size() * sizeof v[0]);
#elif TEST_METHOD == 2
std::fill(v.begin(), v.end(), 0);
#elif TEST_METHOD == 3
for (std::vector<int>::iterator it=v.begin(), end=v.end(); it!=end; ++it) {
*it = 0;
}
#elif TEST_METHOD == 4
v.assign(v.size(),0);
#endif
}
return EXIT_SUCCESS;
}
บทสรุป:ใช้std::fill
(เพราะอย่างที่คนอื่นพูดถึงมันมากที่สุด)!
assign
ช้าลงยกเว้นความจุขนาดเล็ก libc++
บน รหัสcoliru / วาง
fill
ดูแย่มาก มันเป็นคำสั่งสองขนาดที่ช้ากว่าในการทดสอบนี้
วิธีการเกี่ยวกับassign
ฟังก์ชั่นสมาชิก?
some_vector.assign(some_vector.size(), 0);
ถ้ามันเป็นเพียงเวกเตอร์ของจำนวนเต็มฉันจะลองก่อน:
memset(&my_vector[0], 0, my_vector.size() * sizeof my_vector[0]);
มันไม่ได้เป็น C ++ มากดังนั้นฉันแน่ใจว่ามีบางคนที่จะให้วิธีการที่ถูกต้อง :)
::std::fill
วิธีการขยายไปยังสิ่งที่ถูกสาปอย่างรวดเร็วแม้ว่าบิตทางด้านรหัส bloaty เพราะมันเป็นแบบอินไลน์ทั้งหมด ฉันยังคงใช้มันเพราะมันดีกว่าที่จะอ่าน
ลอง
std::fill
และนอกจากนี้ยังมี
std::size siz = vec.size();
//no memory allocating
vec.resize(0);
vec.resize(siz, 0);
ฉันมีคำถามเดียวกัน แต่ค่อนข้างสั้นvector<bool>
(afaik มาตรฐานอนุญาตให้นำมาใช้ภายในแตกต่างจากองค์ประกอบบูลีนต่อเนื่อง) ดังนั้นฉันจึงทำการทดสอบที่แก้ไขเล็กน้อยโดย Fabio Fracassi ซ้ำอีกครั้ง ผลลัพธ์มีดังนี้ (คูณเป็นวินาที):
-O0 -O3
-------- --------
memset 0.666 1.045
fill 19.357 1.066
iterator 67.368 1.043
assign 17.975 0.530
for i 22.610 1.004
เห็นได้ชัดว่าขนาดเหล่านี้vector<bool>::assign()
เร็วกว่า รหัสที่ใช้สำหรับการทดสอบ:
#include <vector>
#include <cstring>
#include <cstdlib>
#define TEST_METHOD 5
const size_t TEST_ITERATIONS = 34359738;
const size_t TEST_ARRAY_SIZE = 200;
using namespace std;
int main(int argc, char** argv) {
std::vector<int> v(TEST_ARRAY_SIZE, 0);
for(size_t i = 0; i < TEST_ITERATIONS; ++i) {
#if TEST_METHOD == 1
memset(&v[0], false, v.size() * sizeof v[0]);
#elif TEST_METHOD == 2
std::fill(v.begin(), v.end(), false);
#elif TEST_METHOD == 3
for (std::vector<int>::iterator it=v.begin(), end=v.end(); it!=end; ++it) {
*it = 0;
}
#elif TEST_METHOD == 4
v.assign(v.size(),false);
#elif TEST_METHOD == 5
for (size_t i = 0; i < TEST_ARRAY_SIZE; i++) {
v[i] = false;
}
#endif
}
return EXIT_SUCCESS;
}
ฉันใช้คอมไพเลอร์ GCC 7.2.0 บน Ubuntu 17.10 บรรทัดคำสั่งสำหรับการรวบรวม:
g++ -std=c++11 -O0 main.cpp
g++ -std=c++11 -O3 main.cpp