Cách nhanh nhất để đặt lại mọi giá trị từ std::vector<int>
0 đến 0 và giữ kích thước ban đầu của vectơ là gì?
Một vòng lặp for với toán tử []?
Cách nhanh nhất để đặt lại mọi giá trị từ std::vector<int>
0 đến 0 và giữ kích thước ban đầu của vectơ là gì?
Một vòng lặp for với toán tử []?
Câu trả lời:
std::fill(v.begin(), v.end(), 0);
v = std::vector<int>(vec_size,0)
) có vẻ nhanh hơn một chút so với fill
trên máy của tôi
assign
.
Như mọi khi bạn hỏi về nhanh nhất: Đo lường! Sử dụng các Phương thức trên (trên máy Mac sử dụng Clang):
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 |
sử dụng 100000 lần lặp trên một vectơ 10000 ints.
Chỉnh sửa: Nếu changeing số này plausibly thay đổi lần kết quả bạn có thể có một số niềm tin (không tốt như kiểm tra mã lắp ráp cuối cùng) mà benchmark nhân tạo chưa được tối ưu hóa đi hoàn toàn. Tất nhiên là tốt nhất để làm hỏng hiệu suất trong điều kiện thực tế. kết thúc chỉnh sửa
để tham khảo mã được sử dụng:
#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;
}
Kết luận: sử dụng std::fill
(bởi vì, như những người khác đã nói thành ngữ nhất của nó)!
assign
chậm hơn, ngoại trừ dung lượng nhỏ trên libc++
. MÃ coliru / dán
fill
vẻ rất tệ. Đó là hai lệnh độ lớn chậm hơn trong thử nghiệm này.
Nếu đó chỉ là một vectơ số nguyên, trước tiên tôi nên thử:
memset(&my_vector[0], 0, my_vector.size() * sizeof my_vector[0]);
Nó không phải là C ++, vì vậy tôi chắc chắn ai đó sẽ cung cấp cách thức phù hợp để làm việc này. :)
::std::fill
phương pháp mở rộng để cái gì đó khá darned nhanh, mặc dù một chút về phía mã bloaty vì nó là tất cả nội tuyến. Tôi vẫn sẽ sử dụng nó bởi vì nó dễ đọc hơn nhiều.
Tôi đã có cùng một câu hỏi nhưng về khá ngắn vector<bool>
(afaik tiêu chuẩn cho phép thực hiện nó bên trong khác với chỉ một mảng các yếu tố boolean liên tục). Do đó tôi lặp lại các bài kiểm tra sửa đổi một chút của Fabio Fracassi. Kết quả như sau (lần, tính bằng giây):
-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
Vì vậy, rõ ràng cho các kích thước, vector<bool>::assign()
là nhanh hơn. Mã được sử dụng để kiểm tra:
#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;
}
Tôi đã sử dụng trình biên dịch GCC 7.2.0 trên Ubuntu 17.10. Dòng lệnh để biên dịch:
g++ -std=c++11 -O0 main.cpp
g++ -std=c++11 -O3 main.cpp