Apa cara tercepat untuk mengatur ulang setiap nilai a std::vector<int>
ke 0 dan menjaga vektor ukuran awal?
A for loop dengan operator []?
Apa cara tercepat untuk mengatur ulang setiap nilai a std::vector<int>
ke 0 dan menjaga vektor ukuran awal?
A for loop dengan operator []?
Jawaban:
std::fill(v.begin(), v.end(), 0);
v = std::vector<int>(vec_size,0)
) tampaknya sedikit lebih cepat daripada fill
di komputer saya
assign
.
Seperti biasa ketika Anda bertanya tentang tercepat: Ukur! Menggunakan Metode di atas (pada Mac menggunakan Dentang):
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 |
menggunakan 100000 iterasi pada vektor 10.000 int.
Edit: Jika changeing nomor ini masuk akal perubahan kali yang dihasilkan Anda dapat memiliki beberapa keyakinan (tidak sebagus memeriksa kode perakitan akhir) bahwa patokan buatan belum dioptimalkan pergi seluruhnya. Tentu saja yang terbaik adalah mengacaukan kinerja dalam kondisi nyata. end Edit
untuk referensi kode yang digunakan:
#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;
}
Kesimpulan: gunakan std::fill
(karena, seperti orang lain katakan paling idiomatis)!
assign
lebih lambat, kecuali untuk kapasitas kecil pada libc++
. CODE coliru / paste
fill
terlihat mengerikan. Ini dua urutan besarnya lebih lambat dalam tes ini.
Bagaimana dengan assign
fungsi anggota?
some_vector.assign(some_vector.size(), 0);
Jika itu hanya vektor bilangan bulat, pertama-tama saya akan mencoba:
memset(&my_vector[0], 0, my_vector.size() * sizeof my_vector[0]);
Ini tidak terlalu C ++, jadi saya yakin seseorang akan memberikan cara yang tepat untuk melakukan ini. :)
::std::fill
Metode memperluas untuk sesuatu yang cukup terkutuk cepat, meskipun sedikit di sisi kode-bloaty karena itu semua inline. Saya masih menggunakannya karena itu jauh lebih baik untuk dibaca.
Saya memiliki pertanyaan yang sama tetapi tentang yang agak pendek vector<bool>
(afaik standar memungkinkan untuk mengimplementasikannya secara internal berbeda dari sekedar array elemen boolean yang berkelanjutan). Karena itu saya mengulangi tes yang sedikit dimodifikasi oleh Fabio Fracassi. Hasilnya adalah sebagai berikut (waktu, dalam detik):
-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
Jadi ternyata untuk ukuran ini, vector<bool>::assign()
lebih cepat. Kode yang digunakan untuk tes:
#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;
}
Saya menggunakan kompiler GCC 7.2.0 di Ubuntu 17.10. Baris perintah untuk kompilasi:
g++ -std=c++11 -O0 main.cpp
g++ -std=c++11 -O3 main.cpp