Самый быстрый способ копирования большого вектора
Есть большой вектор std::vector<unsigned char> Source на 134217728 элементов
И есть пустой std::vector<unsigned char> Copy;
Как быстрее всего и без большого (более 64 Mb) дополнительного расхода памяти скопировать Source в Copy?
Спасибо!
Ответы (2 шт):
Написать vector<unsigned char> Copy = Source; - это будет реально самый быстрый способ :)
Если очень хочется руками...
vector<unsigned char> Copy;
Copy.resize(Source.size());
memcpy(Copy.data(),Source.data(),sizeof(unsigned char)*Source.size());
Примерно так. Но этот способ годится не для любых типов, но для POD - сработает.
Я немного не согласен с Harry в данном случаи. Во первых разберемся что делает Copy.resize(Source.size());
- вызывается
vector::size() - чтобы распределить память для такого количества элементов,
- инициализировав их значением по умолчанию
Дальше
memcpyкопирует все элементы одного вектора в другой, заодно получая указатели на массив (Copy.data() и Source.data()).
Теперь рассмотрим что делает копирующий конструктор вектора.
Этому конструктору известен размер, и ничего не нужно вызывать(хоть и vector::size() встроенная функция, но все же). Если вектор пустой, копирующий конструктор создает неинициализированную область памяти(т.е. нет никаких элементов, а захвачены последовательности байтов) и инициализирует эти поля значениями из элементов другого вектора. Т.е. копирование происходит максимально быстро(быстрее не напишете ни руками, ни другими средствами). И вот доказательство:
class Timer {
using T = std::chrono::time_point<std::chrono::steady_clock>;
T t1, t2;
public:
void start() { t1 = std::chrono::steady_clock::now(); }
void stop() {
t2 = std::chrono::steady_clock::now();
std::cout << '\n' << (t2 - t1).count() << '\n';
}
};
int main() {
std::vector<unsigned char> Source(134217728, 1), Copy;
Timer t1, t2, t3;
t1.start();
vector Copy1 = Source;
t1.stop();
// 80249486
t2.start();
Copy.resize(Source.size());
memcpy(Copy.data(), Source.data(), sizeof(unsigned char) * Source.size());
t2.stop();
// 88608380
return 0;
}
Вообше std::vector написан очень тщательно, и там не найти место, где можно оптимизировать. Единственное, что вы можете сделать, это просто считать копируемый вектор более не нужным и перемещать данные(move конструктор) или менять местами представления векторов применяя std::swap. Так что, даже при том, что memcpy выполняет быстрое копирование, и ответ от Harry является полезным и достоен внимания, я не согласен, что этот способ быстрее.
Можно еще использовать std::array вместо вектора, если удобно использовать его в вашей программе(не всегда же вектор нужно использовать), и тогда копирование будет таким же быстрым, как и для обычных массивов.