A'nın her değerini std::vector<int>
0'a sıfırlamanın ve vektörlerin başlangıç boyutunu tutmanın en hızlı yolu nedir ?
[] Operatörü ile bir döngü için?
A'nın her değerini std::vector<int>
0'a sıfırlamanın ve vektörlerin başlangıç boyutunu tutmanın en hızlı yolu nedir ?
[] Operatörü ile bir döngü için?
Yanıtlar:
std::fill(v.begin(), v.end(), 0);
v = std::vector<int>(vec_size,0)
) fill
makinemden biraz daha hızlı görünüyor
assign
.
Her zaman olduğu gibi en hızlı sorulduğunda: Ölçün! Yukarıdaki Yöntemleri Kullanma (Clang kullanan bir Mac'te):
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 |
10000 ints vektöründe 100000 iterasyon kullanan.
Düzenleme: akla yatkın bu numaralar changeing çıkan kez değiştirirse sahip olabilir bazı güven (değil nihai montaj kod kontrolü olarak iyi gibi) yapay kriter tamamen uzak optimize edilmediğini. Elbette performansı gerçek koşullar altında bozmak en iyisidir. son Düzenle
referans için kullanılan kod:
#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;
}
Sonuç: kullanın std::fill
(çünkü diğerleri en deyimsel demişlerdir)!
assign
küçük kapasiteler hariç daha yavaştır üzerinde libc++
. CODE coliru / paste
fill
korkunç görünüyor. Öyle büyüklükte iki emir yavaş bu testte.
assign
Üye işlevi nasıl olur ?
some_vector.assign(some_vector.size(), 0);
Sadece tamsayıların bir vektörüyse, ilk önce şunu denerdim:
memset(&my_vector[0], 0, my_vector.size() * sizeof my_vector[0]);
Çok C ++ değil, bu yüzden eminim birisi bunu yapmak için uygun bir yol sağlayacaktır. :)
::std::fill
Kod-bloaty tarafında biraz hepsi satır içi olduğundan olsa yöntem, oldukça hızlı darned gelen bir özellik genişler. Yine de kullanardım çünkü okumak çok daha güzel.
Aynı soru vardı ama oldukça kısa vector<bool>
(afaik standart dahili bir boolean öğeleri sürekli dizi daha farklı uygulamayı sağlar). Bu yüzden Fabio Fracassi tarafından hafifçe değiştirilmiş testleri tekrarladım. Sonuçlar aşağıdaki gibidir (kez, saniye cinsinden):
-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
Görünüşe göre bu boyutlar vector<bool>::assign()
için daha hızlı. Testler için kullanılan kod:
#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;
}
Ubuntu 17.10'da GCC 7.2.0 derleyicisini kullandım. Derleme için komut satırı:
g++ -std=c++11 -O0 main.cpp
g++ -std=c++11 -O3 main.cpp