I have multidimensional array of Struct in C++.
#define TOTALSTREAMS 5
#define SEQUENCEHISTORY 20
#define PROCESSINGSIZE 5
#define OVERLAPPINGSIZE 1
#define X_GRID 100//X_GRID and Y_GRID represents the whole building in CM
#define Y_GRID 70
typedef struct {
uint64_t localid;
uint64_t globalid;
int posture;
std::vector<float> feature;
} person;
typedef struct {
std::vector<person> people;
} griddata;
griddata History_host[SEQUENCEHISTORY][TOTALSTREAMS][Y_GRID][X_GRID];
griddata Processed_Array[PROCESSINGSIZE][TOTALSTREAMS][Y_GRID][X_GRID];
Need to copy from one array to another. What I did was just copy in simple way as follows. It is slow. How can I copy such array in faster way?
for(int i=0; i<PROCESSINGSIZE; i++){
for(int j=0; j<TOTALSTREAMS; j++){
for(int k=0; k<Y_GRID; k++){
for(int m=0; m<X_GRID; m++){
for(int n=0; n<History_host[i][j][k][m].people.size(); n++){
Processed_Array[i][j][k][m].people.push_back(History_host[i][j][k][m].people.back());
}
}
}
}
}
The code you have posted does not copy the arrays content properly. The assignment
Processed_Array[i][j][k][m].people.push_back(History_host[i][j][k][m].people.back());
will not copy the arrays content, but only add the last element of the source array several times. You should use the index n to access the appropriate element.
Here are some hints to increase the copy speed:
You could use std::copy
:
//inner loop
for (size_t n = 0; n < History_host[i][j][k][m].people.size(); n++) {
std::copy(History_host[i][j][k][m].people.begin(),
History_host[i][j][k][m].people.end(),
Processed_Array[i][j][k][m].people.begin());
}
//...
It seems to be a better option when compared to direct assignment or Alan's sugestion. You can see here all the 3 methods side by side.
Still, you don't explain exactly what this is for, it's possible there are better options to do what you need. You could be facing the XY problem .
Biggest problem I see it that this code is to much C
-like.
typedef
which is a good practice in C
and obsolete in C++
. To make this more like C++ code:
constexpr size_t TOTALSTREAMS = 5;
constexpr size_t SEQUENCEHISTORY = 20;
constexpr size_t PROCESSINGSIZE = 5;
constexpr size_t OVERLAPPINGSIZE = 1;
constexpr size_t X_GRID = 100; //X_GRID and Y_GRID represents the whole building in CM
constexpr size_t Y_GRID = 70;
struct person{
uint64_t localid;
uint64_t globalid;
int posture;
std::vector<float> feature;
};
struct griddata{
std::vector<person> people;
};
using griddata_streams = std::array<std::array<std::array<griddata, X_GRID>, Y_GRID>, PROCESSINGSIZE>;
using history_host = std::array<griddata_streams, SEQUENCEHISTORY>;
using processed_array = std::array<griddata_streams, PROCESSINGSIZE>;
history_host History_host;
processed_array Processed_Array;
Now simple assignment does the job and other parts of code remains unchanged.
Now about performance. To improve there are only tree choices:
push_back
it can reallocate vector buffer multiple times as vector grows. Use of std::vector::reserve
can prevent this. Note also that your original code has UB: buffer overflow, since SEQUENCEHISTORY > PROCESSINGSIZE
.
To copy this you can do this:
std::copy_n(History_host.begin(), std::min(History_host.size(), Processed_Array.size()),
Processed_Array.begin());
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.