Roy Huang
Roy Huang

Reputation: 629

Copy constructor works faster on copying std::vector<int64_t> than std::copy

#include <iostream>
#include <vector>
#include <chrono>
#include <string.h>

std::vector<int64_t> vec;
static const int64_t N = 100000000;
static const int64_t M = N - 1;

void func1() {
    std::cout << __FUNCTION__ << std::endl;
    std::vector<int64_t> dst;
    dst.resize(M);
    std::copy(vec.begin(), vec.begin() + M, dst.begin());
}

void func2() {
    std::cout << __FUNCTION__ << std::endl;
    std::vector<int64_t> dst;
    dst.resize(M);
    memcpy(&dst[0], &vec[0], M * sizeof(int64_t));
}
void func3() {
    std::cout << __FUNCTION__ << std::endl;
    std::vector<int64_t> dst(vec);
    dst.resize(M);
}

int main(int argc, char* argv[]) {
    vec.resize(N);
    for (int i = 0; i < N; i++) {
        vec[i] = i;
    }

    auto begin = std::chrono::steady_clock::now();
    if (argc == 1) {
        func1();
    } else if (argc == 2) {
        func2();
    } else {
        func3();
    }
    auto end = std::chrono::steady_clock::now();
    std::cout << "Time difference = "
        << std::chrono::duration_cast<std::chrono::microseconds> \
        (end - begin).count()
        << "[µs]" << std::endl;
    return 0;
}

I thought std::copy might be slightly faster than copy constructor, as func1() vs func3().

But it turned out that func3() had best performance. Why?

func3 Time difference = 658007[µs]

func2 Time difference = 823092[µs]

func1 Time difference = 838711[µs]

I've also tested std::vector, func1 faster than func3. SomeStruct includes std::string and

struct A {
    A(int64_t a) : A_(a) {}
    int64_t a_;
};

compile command: g++ test.cpp -std=c++11 I ran several times and the results seem the same.

Upvotes: 0

Views: 493

Answers (1)

ivan.ukr
ivan.ukr

Reputation: 3551

Copy constructor can copy content of a source vector directly into newly allocated uninitialized memory, especially if contained type is primitive type or POD. Vector implementations are often optimized for this. And on the other hand, call to resize() has to fill newly allocated space with default value (or value that you have specified to resize()), because vector elements cannot be uninitialized. This obviously takes additional time. That's why func1() and func(2) are slower.

Upvotes: 4

Related Questions