Melihat output perakitan, gcc sebenarnya membuka gulungan lingkaran ini untuk menggunakan register mmx untuk membuang dalam 16 byte pada suatu waktu sampai mendekati akhir. Saya katakan itu cukup cepat. Versi memset melompat ke memset, yang saya kira hampir secepat. Saya akan menggunakan metode Anda.
Mahakuasa
Tetapi, melompat ke memset adalah instruksi tunggal, jadi menggunakannya akan menghasilkan ukuran biner yang lebih kecil.
Alexander Shishenko
2
ini bukan apa yang diminta OP, tetapi hanya menugaskan kembali vektor Anda ke yang baru dengan ukuran yang sama ( v = std::vector<int>(vec_size,0)) tampaknya sedikit lebih cepat daripada filldi komputer saya
Yibo Yang
1
Ini adalah cara paling idiomatis untuk melakukannya, lebih idiomatis daripada menggunakan assign.
alfC
1
apakah menugaskan ke vektor baru melakukan penumpukan alokasi? dan kemudian buang alokasi vektor yang ada? Saya bisa melihat bahwa menjadi lebih lambat daripada memset et al
Conrad Jones
150
Seperti biasa ketika Anda bertanya tentang tercepat: Ukur! Menggunakan Metode di atas (pada Mac menggunakan Dentang):
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
+1. Benchmark khusus ini tidak konklusif, tetapi intinya benar-benar benar, Anda harus menulis tes kinerja alternatif karena mereka benar-benar akan digunakan. Jika tidak ada perbedaan kinerja, gunakan sumber mana yang paling sederhana.
Steve Jessop
3
"... tidak konklusif ..." IMO ketidakkonsistenan ini dalam dirinya sendiri sudah merupakan poin yang baik untuk melakukan benchmark, lebih sering daripada tidak Pengoptimal sudah melakukan pekerjaan yang sangat baik untuk jenis situasi yang ditanyakan OP. Dan saya akan memodifikasi kalimat terakhir Anda untuk membaca "Jika tidak ada perbedaan kinerja yang signifikan ..."
Juga, wow, jika Anda peduli tentang kecepatan tanpa optimisasi (yang mungkin masuk akal jika Anda menggunakan mode 'debug', yang dilakukan beberapa tim), fillterlihat mengerikan. Ini dua urutan besarnya lebih lambat dalam tes ini.
Kyle Strand
5
@KyleStrand: Bukan isinya mengerikan, tapi templat dan kode dihasilkan dengan -O0 di dalam unit terjemahan Anda. Saat Anda menggunakan memset, Anda menggunakan kode libc yang dikompilasi dengan -O3 (bahkan ketika Anda mengkompilasi kode Anda dengan -O0). Jika Anda peduli tentang kecepatan dalam debug dan Anda menggunakan templat, Anda harus menggunakan instantiasi templat eksplisit dalam file terpisah yang Anda kompilasi dengan -O3
Karena standar (2003 TC1) menjamin bahwa std :: vector bersebelahan dalam memori, ini harus baik-baik saja. Jika pustaka c ++ Anda tidak sesuai dengan TC1 2003, maka jangan gunakan ini.
Mario
2
@ Mario: Saya tidak akan memposting ini kecuali itu benar dan diasumsikan terkenal, tentu saja. :) Tapi terima kasih.
bersantai
1
Saya memeriksa perakitan. The ::std::fillMetode 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.
Mahakuasa
4
Anda sebaiknya menambahkan memeriksa apakah vektor kosong dan tidak melakukan apa pun dalam kasus ini. Menghitung & membeli [0] untuk vektor kosong dapat menghasilkan pernyataan dalam kode STL.
Sergey
4
mencoba
std::fill
dan juga
std::size siz = vec.size();//no memory allocating
vec.resize(0);
vec.resize(siz,0);
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.6661.045
fill 19.3571.066iterator67.3681.043
assign 17.9750.530for i 22.6101.004
Jadi ternyata untuk ukuran ini, vector<bool>::assign()lebih cepat. Kode yang digunakan untuk tes:
Jawaban:
sumber
v = std::vector<int>(vec_size,0)
) tampaknya sedikit lebih cepat daripadafill
di komputer sayaassign
.Seperti biasa ketika Anda bertanya tentang tercepat: Ukur! Menggunakan Metode di atas (pada Mac menggunakan Dentang):
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:
Kesimpulan: gunakan
std::fill
(karena, seperti orang lain katakan paling idiomatis)!sumber
assign
lebih lambat, kecuali untuk kapasitas kecil padalibc++
. CODE coliru / pastefill
terlihat mengerikan. Ini dua urutan besarnya lebih lambat dalam tes ini.Bagaimana dengan
assign
fungsi anggota?sumber
Jika itu hanya vektor bilangan bulat, pertama-tama saya akan mencoba:
Ini tidak terlalu C ++, jadi saya yakin seseorang akan memberikan cara yang tepat untuk melakukan ini. :)
sumber
::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.mencoba
dan juga
sumber
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):Jadi ternyata untuk ukuran ini,
vector<bool>::assign()
lebih cepat. Kode yang digunakan untuk tes:Saya menggunakan kompiler GCC 7.2.0 di Ubuntu 17.10. Baris perintah untuk kompilasi:
sumber