簡體   English   中英

C++ 中大型整數數組的最佳實踐

[英]Best practices for large array of integers in C++

我正在加載一個 123 MB 的無符號整數文件,該文件需要在 C++ 中的 memory(用於蒙特卡羅模擬的快速查找)中。 現在我有一個全局數組,但我聽說全局 arrays 不受歡迎。 這方面的最佳做法是什么?

就上下文而言,我正在對撲克游戲進行蒙特卡洛模擬,需要一個大約 3000 萬個整數的數組來快速計算撲克手的贏家。 要確定獲勝者,您首先通過對數組進行 7 次查詢來計算“handranks”。 然后確定獲勝者,你比較'handranks'。

int HR[32487834];

int get_handrank(const std::array<int,7> cards)
{
  int p = 53;
  for (const auto& c: cards)
    p = HR[p + c];
  return p; 
}

int main()
{
  // load the data
  memset(HR, 0, sizeof(HR));
  FILE * fin = fopen("handranks.dat", "rb");
  if (!fin)
    std::cout << "error when loading handranks.dat" << std::endl;
  size_t bytesread = fread(HR, sizeof(HR), 1, fin);
  fclose(fin);
  std::cout << "complete.\n\n";

  // monte carlo simulations using get_handrank() function
  .
  .
  .
}
  1. 使用局部變量,並根據需要將它們傳遞給函數。 這使得程序更容易推理。

  2. 對於這么大的數據,使用vector而不是數組,否則可能會導致堆棧溢出。

  3. 修改您的函數以使用std::span而不是特定容器,因為這會產生更多的解耦。

  4. 使用有意義的名稱為32487834創建一個符號常量,而不是將其用作魔術常量。

使用局部變量並傳遞它們總是比使用全局變量 IMO 更好的做法。 它使您的算法更加靈活。 如果以后由於某種原因需要使用不同的數組怎么辦? 您需要使用全局變量修改所有函數。 我同意傳遞數組有點不方便和冗長,但仍然比全局更好。 我們稍后會解決這個問題。

所以你的第一個選擇是這樣的:

// Don't forget to receive the params as references to avoid copying
int get_handrank(const std::array<int,7>& cards, const std::array<int, 32487834>& HR)
{
  int p = 53;
  for (const auto& c: cards)
    p = HR[p + c];
  return p; 
}

int main()
{
  std::array<int, 32487834> HR{}; //zero-inits the array
  // or std::vector<int> HR{}; HR.resize(32487834) to avoid stack overflow as @MarkRansom pointed out

  FILE * fin = fopen("handranks.dat", "rb");
  if (!fin)
    std::cout << "error when loading handranks.dat" << std::endl;
  size_t bytesread = fread(HR.data(), HR.size() * sizeof(int), 1, fin);
  fclose(fin);
}

第二種方法,甚至更好:使用類。 您可以模擬 class,並且 class 可以將 HR 數組作為 const 私有成員在構造函數中讀取和初始化。 那么get_handrank可以是成員 function 並且可以訪問成員 HR 數組:

class Simulation {
public: 
  int get_handrank(const std::array<int,7>& cards)
  {
    int p = 53;
    for (const auto& c: cards)
      p = HR[p + c];
    return p; 
  }

  Simulation()
    : HR{} 
    // or HR{readHRFromFileFunction()}
  {
    FILE * fin = fopen("handranks.dat", "rb");
    if (!fin)
      std::cout << "error when loading handranks.dat" << std::endl;
    size_t bytesread = fread(HR.data(), HR.size() * sizeof(int), 1, fin);
    fclose(fin);
  }

private:
  std::array<int, 32487834> HR;
  //or const std::array<int, 32487834> HR; if you use a function to init it
}

暫無
暫無

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

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