簡體   English   中英

為什么不總是實例化堆棧上的對象? C ++

[英]Why not always instantiate objects on the stack? C++

劇透只包含背景和上下文

這篇文章提到 ,要避免這樣的事實,即當對象超出范圍時,它會被釋放,只需將對象返回堆棧分配的對象,使其保留在范圍內即可。 顯然,這會在其他位置在堆棧上復制對象。 這個家伙甚至確認您應該始終喜歡分配到堆棧。 在C ++中,使用類似以下內容的代碼:

Object* my_object = new Object();

動態地實例化一個對象到堆,但是! Object my_object = Object();

實例化堆棧上的對象。 堆棧的大小受到限制,而堆實際上沒有限制(物理限制除外)。 而且,根據這篇文章 ,堆棧訪問時間要快得多,並且當超出范圍時,當然釋放是自動的。


我正在嘗試創建一個對速度絕對至關重要的應用程序,難道我不能只在main內實例化堆棧上的所有對象,而只是將嵌套范圍內的每個實例保存到外部容器中嗎?

我使用包含屬性“ id”的簡單Node類自己對此進行了測試。 我實例化了堆棧上的節點,將它們放在向量中,這樣就不會釋放它們,然后(只是檢查)我將新項目分配到堆棧,然后檢查以確保仍然存在先前分配的數據。 我可以繼續在一個規模較大的問題上實現這一點嗎?

int main()
{
  vector<Node> stack_nodes;
  for (int i = 0; i < 2; ++i)
  {
    stack_nodes.push_back(Node(i)); // push newly copied stack-allocated objects so they don't die 
  }
  Node new_node1 = Node(3); // allocate two more to test stack memory overwriting 
  Node new_node2 = Node(4);
  cout << stack_nodes.at(1).getID(); // outputs 1! It's still there?
  return 0;
}

編輯:請參閱下面的評論。 從創建它的作用域返回堆棧分配的對象時,將創建該對象的副本。 該副本是否也在堆棧上? 如果我將復制的對象分配給在main范圍內聲明的向量,該對象是否仍在堆棧中?

我不能只實例化main中堆棧上的所有對象嗎?

如果您可以說明所有需要的對象,則可以

哎呀,COBOL采取了這種方法。 “這是您永遠需要的每個變量……”

我可以繼續在一個規模較大的問題上實現這一點嗎?

有無限的內存,是的。 總是。

使用有限的內存,您可能需要管理對象的生存期,並且僅在任何時候都需要實際需要的內存。

在某些情況下,您當然可以對某些程序執行此操作。 舉例來說,回想過去,Fortran的定義是為了使程序使用的所有數據可以靜態分配(這是常規方式)。

同時,這是非常有限的並且有問題。 僅舉幾個例子,它排除了(幾乎)所有遞歸,這對於處理某些類型的遞歸數據結構(例如樹)確實非常方便。

這也意味着所有變量實際上都是全局變量,因此(例如)程序中的任何代碼都可以讀取和/或寫入程序中的幾乎任何變量。 具有使用該模型的Fortran和BASIC(早期版本)等語言的經驗表明,開發當前被視為中小型程序的程序需要大量的紀律,並且開發通常被視為大型系統的程序可能幾乎不可能。 代碼不同部分之間的依賴關系變得如此復雜,以至於幾乎不可能確定在哪里使用了什么,哪些部分取決於其他部分等等。

我懷疑這在實踐中是否合理。 分配堆棧空間的開銷開出如此微不足道是消除它根本不會受到任何顯着的程度的提高速度。 實際上,它可能很容易做到相反。 預分配變量意味着(必不可少的)每個變量都將駐留在內存的唯一部分中。 在給定的時間中,它們中的很大一部分將用於當前不在緩存中的內存部分,因此您最終會遇到較差的引用局部性,從而導致較差的緩存使用率。

輸入函數時分配本地數據意味着大多數變量都位於棧頂或棧頂附近。 由於您幾乎一直在使用靠近堆棧頂部的內存,因此該內存大部分時間都保留在緩存中,因此幾乎所有的內存訪問都命中了緩存。

分配時間通常(遠遠)低於1%,但是訪問主內存而不是高速緩存的代價通常至少是10倍,並且通常要高得多(通常20到50倍)。 根據數據訪問方式的不同,里程數會有所不同,但是您有巨大的潛在巨大損失,(最多)只有很小的機會獲得微不足道的收益。

簡介:這是一個糟糕的想法。 容易做了很多的傷害比好,甚至一點點。

暫無
暫無

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

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