Я использую все время одно и то же std::vector<int>
для того, чтобы попытаться избежать выделения сделки все время. В нескольких строках мой код выглядит следующим образом:
std::vector<int> myVector;
myVector.reserve(4);
for (int i = 0; i < 100; ++i) {
fillVector(myVector);
//use of myVector
//....
myVector.resize(0);
}
В каждой итерации, myVector
будет заполнено до 4 элементов. Для того, чтобы сделать эффективный код, я хочу использовать всегда myVector
, Однако в myVector.resize()
элементы в myVector
разрушаются. Я это понимаю myVector.clear()
будет иметь тот же эффект.
Я думаю, если бы я мог просто перезаписать существующие элементы в myVector
Я мог бы сэкономить время. Однако я думаю, что std::vector
не способен сделать это.
Есть ли способ сделать это? Имеет ли смысл создавать доморощенную реализацию, которая перезаписывает элементы?
std :: vector не является решением в этом случае. Вы не хотите изменить размер / очистить / (де) выделить заново? Не.
Хорошо. Используйте простую структуру:
struct upTo4ElemVectorOfInts
{
int data[4];
size_t elems_num;
};
И измените fillVector (), чтобы сохранить дополнительную информацию:
void fillVector(upTo4ElemVectorOfInts& vec)
{
//fill vec.data with values
vec.elems_num = filled_num; //save how many values was filled in this iteration
}
Используйте это так же:
upTo4ElemVectorOfInts myVector;
for (int i = 0; i < 100; ++i)
{
fillVector(myVector);
//use of myVector:
//- myVector.data contains data (it's equivalent of std::vector<>::data())
//- myVector.elems_num will tell you how many numbers you should care about
//nothing needs to be resized/cleared
}
Дополнительное примечание:
Если вы хотите более общее решение (для работы с любым типом или размером), вы можете, конечно, использовать шаблоны:
template <class T, size_t Size>
struct upToSizeElemVectorOfTs
{
T data[Size];
size_t elems_num;
};
и настройте fillVector () для принятия шаблона вместо известного типа.
Это решение, вероятно, самое быстрое. Вы можете подумать: «Эй, а если я захочу заполнить до 100 элементов? 1000? 10000? Что тогда? 10000-элементный массив будет занимать много памяти!».
Это все равно потребляет. Vector автоматически изменяет размеры, и это перераспределяется вне вашего контроля и, следовательно, может быть очень неэффективным. Если ваш массив достаточно мал и вы можете предсказать максимальный требуемый размер, всегда используйте хранилище фиксированного размера, созданное в локальном стеке. Это быстрее, эффективнее и проще. Конечно, это не будет работать для массивов из 1.000.000 элементов (вы получите Переполнение стека в этом случае).
Ваш код уже действителен (myVector.clear()
имеет лучший стиль, чем myVector.resize(0)
хоть).
int int destructor ничего не делает.
Так resize(0)
просто устанавливает size
до 0, capacity
нетронутым
Просто не продолжайте изменять размер myVector
, Вместо этого инициализируйте его с 4 элементами (с std::vector<int> myVector(4)
) и просто назначьте элементам (например, myVector[0] = 5
).
Однако, если он всегда будет фиксированного размера, вы можете использовать std::array<int, 4>
,
Изменение размера вектора до 0 не уменьшит свою емкость и, так как ваш тип элемента int
нет деструкторов для запуска:
#include <iostream>
#include <vector>
int main() {
std::vector<int> v{1,2,3};
std::cout << v.capacity() << ' ';
v.resize(0);
std::cout << v.capacity() << '\n';
}
// Output: 3 3
Поэтому ваш код уже работает в основном оптимально; единственная дополнительная оптимизация, которую вы могли бы сделать, это избежать изменения размера полностью, тем самым теряя внутренний «установить размер на 0» внутри std::vector
что, вероятно, сводится к if
заявление и изменение значения элемента данных.
На самом деле то, что у вас есть в настоящее время
for (int i = 0; i < 100; ++i) {
myVector.reserve(4);
//use of myVector
//....
myVector.resize(0);
}
Я не вижу никакого смысла в этом коде.
Конечно, было бы лучше использовать myVector.clear()
вместо myVector.resize(0);
Если вы всегда перезаписываете ровно 4 элемента вектора внутри цикла, вы можете использовать
std::vector<int> myVector( 4 );
вместо
std::vector<int> myVector;
myVector.reserve(4);
при условии, что функция fillVector (myVector); использует оператор индекса для доступа к этим 4 элементам вектора вместо функции-члена push_back
В противном случае используйте clear
как это было рано предложено.