Какой самый быстрый способ сбросить каждое значение a std::vector<int>
до 0 и сохранить начальный размер векторов?
А для цикла с оператором []?
Какой самый быстрый способ сбросить каждое значение a std::vector<int>
до 0 и сохранить начальный размер векторов?
А для цикла с оператором []?
Ответы:
std::fill(v.begin(), v.end(), 0);
v = std::vector<int>(vec_size,0)
) кажется немного быстрее, чем fill
на моей машине
assign
.
Как всегда, когда вы спрашиваете о самом быстром: Мера! Используя Методы выше (на Mac, используя 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 |
используя 100000 итераций для вектора 10000 целых.
Изменить: Если изменение этих чисел правдоподобно меняет результирующее время, вы можете иметь некоторую уверенность (не так хорошо, как проверка кода окончательной сборки), что искусственный тест не был полностью оптимизирован. Конечно, лучше всего испортить представление в реальных условиях. конец Править
для справки использованный код:
#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++
. CODE coliru / paste
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 стороне , так как это все инлайн. Я все еще использовал бы это, хотя, потому что это намного лучше читать.
У меня был тот же вопрос, но относительно довольно короткий vector<bool>
(на самом деле стандарт позволяет реализовать его внутренне иначе, чем просто непрерывный массив логических элементов). Поэтому я повторил слегка измененные тесты Фабио Фракасси. Результаты следующие (раз в секундах):
-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