简体   繁体   中英

C++ Build an array of data by repeating a vector many times

I have a sequence of numbers that I need to repeat many times and get the repeated data as a pointer to the data along the size (actually element count). I need that data to pass it on to an API.

What would be the most efficient way to allocate the memory, pass on the repeated data and then free it again. I currently have the sequence that needs to be repeated stored in a std::vector

A couple of thoughts I had were along the lines of:

// Setup code
unsigned int repeat = 30000;
std::vector<int> datavector(5, 0); // assume this would contain arbitrary numbers that needed to be repeated

// Idea 1:
{
    unsigned int byte_size_step = datavector.size() * sizeof(int);
    unsigned int byte_full_size = byte_size_step * repeat;
    int *ptr = malloc(byte_full_size);

    for(unsigned int i=0; i<repeat; i++)
    {
        memcpy(ptr+(i*byte_size_step), datavector.data(),  byte_size_step);
    }
    apiFunc(ptr); // apiFunc copies the data
    free(ptr)
}

// Idea 2:
{
    std::vector datarepeated(datavector.size()*repeat);
    for(unsigned int i=0; i<repeat; i++)
    {
        datarepeated.insert(datarepeated.begin()+(i*size_step), datavector.begin(), datavector.end());
    }
    apiFunc(datarepeated.data());
}

Though I felt that there would be a function or easy-to-go method laying around to quickly repeat the sequence in memory. I'm probably missing something. I personally don't know if something like this could benefit from a multithreaded solution.

Any tips to do this (most) efficiently are welcome.

Both your ideas should have very similar performance. You might, however be able to squeeze a bit more performance out of it by minimizing the number of loop iterations/ memcpy calls which you can do by doubling the length at each iteration. Something like this:

// Setup code
const size_t repeat = 10;
int data[] = {1, 2, 3, 4, 5};
vector<int> datavec(data, data+5);

// initialize and copy initial segment
vector<int> datarepeated(datavec.size() * repeat);
memcpy(&datarepeated[0], &datavec[0], datavec.size()*sizeof(int));
size_t num_copied = datavec.size();
size_t num_total = datarepeated.size();

// double the amount copied at each iteration
while(num_copied*2 <= num_total) {
    memcpy(&datarepeated[num_copied], &datarepeated[0], num_copied*sizeof(int));
    num_copied *= 2;
}

// copy the final bit
if(num_copied < num_total)
    memcpy(&datarepeated[num_copied], &datarepeated[0], (num_total-num_copied)*sizeof(int));

You can see it in action here .

EDIT: Of course, you can try variations on how you do the copying (eg, instead of memcpy , use std::copy with a back_inserter as someone suggested in comments) inside the while loop. The key idea I'm trying to express is doing this repeated doubling. Whatever you end up trying, be sure to benchmark .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM