簡體   English   中英

C++中復制多維數組的快速方法

[英]Fast way of copying multidimensional array in C++

我在 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];

需要從一個數組復制到另一個數組。 我所做的只是簡單地復制如下。 它很慢。 我怎樣才能更快地復制這樣的數組?

          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());
                      }
                   }
                }
             }
          }     

您發布的代碼沒有正確復制 arrays 內容。 那作業

Processed_Array[i][j][k][m].people.push_back(History_host[i][j][k][m].people.back());

不會復制 arrays 內容,而只會將源數組的最后一個元素添加幾次。 您應該使用索引 n 來訪問適當的元素。

以下是提高復制速度的一些提示:

  • 在使用 std::vector<>.push_back() 之前,使用 std::vector<>.reserve() 分配向量元素。 向量將在沒有給出初始大小的情況下動態增長,這是一項昂貴的操作。
  • 盡量避免使用 std::vector<> 並使用固定大小的 arrays (如果可能)。 固定大小的 arrays 可以使用 memcpy() 輕松復制

您可以使用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());
}
//...

與直接分配或 Alan 的建議相比,這似乎是一個更好的選擇。 您可以在此處並排查看所有 3 種方法。

不過,您並沒有確切解釋這是做什么用的,可能有更好的選擇來滿足您的需求。 您可能面臨XY 問題

最大的問題我認為這段代碼與C

  • 常量使用宏
  • 使用顯式 C 數組
  • typedefC++中是一個很好的做法,在C中已過時。

為了使它更像 C++ 代碼:

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;

現在簡單的賦值完成了這項工作,代碼的其他部分保持不變。

現在關於性能。 為了改進,只有樹選擇:

  • 上面的代碼 - push_back存在問題,它可以隨着向量的增長多次重新分配向量緩沖區。 使用std::vector::reserve可以防止這種情況。
  • 使用 COW - Copy On Write 技術(無需額外的問題上下文即可完成)
  • 分析此代碼應解決的問題並在那里尋找可能的優化。 為此,我們只需要知道您的代碼做什么以及您的輸入數據的屬性是什么。 例如,有一種叫做稀疏矩陣的東西可以極大地提高性能。

另請注意,您的原始代碼有 UB: buffer overflow,因為SEQUENCEHISTORY > PROCESSINGSIZE

要復制它,您可以這樣做:

std::copy_n(History_host.begin(), std::min(History_host.size(), Processed_Array.size()),
            Processed_Array.begin());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM