У меня есть функция, которая создает большой вектор для своей внутренней работы. Скажем, нам нужно также вызывать эту функцию много раз. Какой лучший способ справиться с созданием / уничтожением памяти вектора (факторы — производительность, качество кода ..)
Способ 1:
void f(int n) {
vector<int> v(n);
}
int main() {
for (int i = 0; i < 1000000; ++i) f(10000000);
}
Способ 2:
void f(int n) {
static vector<int> v;
v.reserve(99999999); // say this is the maximum possible size
v.resize(n);
}
int main() {
for (int i = 0; i < 1000000; ++i) f(10000000);
}
Метод 2 определенно быстрее, чем метод 1, но выглядит ужасно.
Какой будет лучший подход
Преврати функцию в класс с operator()
,
class f_class {
std::vector<int> v;
public:
f_class()
{
v.reserve(99999999);
}
void operator()(int n)
{
v.resize(n);
// Whatever the original f() did
}
};
int main() {
f_class f;
for (int i = 0; i < 1000000; ++i) f(i);
}
Согласно вашему примеру, ваш векторный размер такой же, так почему бы не создать только один вектор?
using namespace std;
void f(vector<int>& v) {
// Do something with vector
}
int main() {
int n = 10000000;
vector<int> v(n);
for (int i = 0; i < 1000000; ++i)
f(v);
}
v.reserve() //deals with capacity.
v.resize(n) //deals with size.
В методе 2 то, что испытывает статический вектор, — это просто изменение размера, однако зарезервированное пространство больше, чем размер, поэтому емкость не изменяется, а когда вы выполняете цикл в цикле, он просто увеличивается на один. Поэтому размер просто увеличивается на единицу каждый раз. Емкость не меняется. Обычно если resize вызывается для пустого вектора типа int, векторные элементы в этом диапазоне изменения размера будут инициализированы в 0.
В методе 1 вектор создается с размером n, но с наиболее близким значением n<2 ^ k целочисленное значение как емкость (например, если n = 100, то емкость 128, когда n = 200, емкость 256 и т. Д.). Кроме того, когда вы вызываете метод one, вы создаете и уничтожаете каждый раз, когда функция выходит из области видимости. Следует отметить, что вектор пуст, так как он не имеет никаких значений.
В методе 2 вектор является статическим и остается.
Вы может хочу почитать:
Кроме того, если у вас есть векторная резервная память, и предполагается, что вы может не будет беспокоиться об объеме памяти, предварительное выделение памяти с постоянными вставками с помощью амортизированного анализа будет иметь Big-O (1) для каждой операции.