Некоторые способы оптимизации производительности std::vector:

1. Предпочитайте emplace_back() вместо push_back() при вставке в вектор.

2. При переборе элементов в std::vector избегайте использования функции std::vector::at().

3. При заполнении или копировании в вектор предпочитайте присваивание, а не вставку() или push_back().

4. Избегайте ненужных циклов перераспределения и копирования, резервируя размер вектора заранее.

5.Используйте сжатие_к_подгонке(), чтобы освободить память, используемую вектором — очистка() или стирание() не освобождают память.

Чтобы объяснить вышеупомянутые моменты, я взял два примера кода, чтобы показать различные типы оптимизации в std::vector.

а.) неоптимизированный код:

#include <iostream>
#include<vector>

class cord{
    public:
    int x,y,z;
    cord(int x,int y,int z):x(x),y(y),z(z)
    {
        
    }
    cord(const cord&)
    {
       std::cout<<"copy constructor called"<<std::endl;   
    }
};
int main()
{
    std::vector<cord> v;
    v.push_back({1,2,3});
    v.push_back({4,5,6});
}

вывод:

copy constructor called
copy constructor called
copy constructor called

Как вы можете видеть, конструктор копирования вызывается в выходных данных трижды. Один для копирования шнура объекта класса {1,2,3} из кадра стека int main() в вектор. Второй во время изменения размера и повторного размещения в векторе с измененным размером. Третий для копирования {4,5,6} из кадра стека int main() снова в вектор.

б.) Давайте посмотрим на оптимизированную версию этого кода:

#include <iostream>
#include<vector>

class cord{
    public:
    int x,y,z;
    cord(int x,int y,int z):x(x),y(y),z(z)
    {
        
    }
    cord(const cord&)
    {
       std::cout<<"copy constructor called"<<std::endl;   
    }
};
int main()
{
    std::vector<cord> v;
    v.reserve(3);
    v.emplace_back(1,2,3);
    v.emplace_back(4,5,6);
}

вывод:

‹Конструктор копирования не вызывается›

В этом примере конструктор копирования не вызывается ни разу, потому что мы уже зарезервировали память для 3 элементов в векторе, используя резервный метод для вектора. И метод emplace_back() напрямую создает объект в самой векторной памяти, а не копирует откуда-то еще.