- 堆分配的確的確相當昂貴。
- 不成熟的優化是不好的,但如果你的圖書館是相當一般和矩陣是巨大的,尋求一個有效的設計可能並不成熟。畢竟,在你積累了許多依賴之後,你不想修改你的設計。
- 有各種層次可以解決這個問題。例如,您可以通過在內存分配程度級別解決堆分配開銷(例如,每個線程內存池),而堆分配很昂貴,您正在創建一個巨型矩陣來執行一些相當昂貴的操作在矩陣上(通常線性複雜或更差)。相對而言,在免費商店中分配一個矩陣可能並不是那麼昂貴,相比之下你隨後不可避免地要做的事情,因此與類似於排序的函數的整體邏輯相比,它實際上可能相當便宜。
我建議你自然地寫代碼,考慮#3作爲未來的可能性。也就是說,不要參考用於中間計算的矩陣緩衝區來加速創建臨時對象。製作臨時表格並按價值歸還。正確性和良好,清晰的接口是第一位的。
晴這裏的目標是分離的矩陣(通過分配器或其他方式)的造物政策,爲您提供了喘息的空間,以優化作爲一種事後不改變太多現有的代碼。如果你可以通過修改所涉及功能的實現細節來做到這一點,或者更好的做法是隻修改你的矩陣類的實現,那麼你真的很好,因爲那樣你就可以自由地在不改變設計的情況下進行優化,並且從效率的觀點來看,任何設計都可以完成。
警告:以下內容僅適用於如果您真的想要充分利用每個週期。理解#4並且讓自己成爲一名優秀的分析師是至關重要的。還值得注意的是,通過優化這些矩陣算法的內存訪問模式,您可能會做得更好,而不是試圖優化堆分配。
如果您需要優化內存分配,請考慮使用像每個線程內存池一般的東西對其進行優化。例如,你可以讓你的矩陣採用可選的分配器,但是我強調這裏是可選的,我也會首先用一個簡單的分配器實現強調正確性。
換句話說:
是更好的做法是每個函數內聲明M1(N,P),或 而一勞永逸在main(),並把它傳遞給每一個被用作 一種桶,每個功能可以用作廢品空間。
繼續創建M1在每個功能的暫時的。儘量避免要求客戶製作一些對他/她沒有意義的矩陣來計算中間結果。這將暴露一個優化細節,這是我們在設計接口時應該努力不去做的事情(隱藏客戶端不應該知道的所有細節)。
相反,着眼於更廣泛的概念,如果你絕對要該選項,以加速這些臨時對象的創建,如可選的分配器。這與實用的設計適合於像std::set
:
std::set<int, std::less<int>, MyFastAllocator<int>> s; // <-- okay
即使大多數人只是做:
std::set<int> s;
在你的情況,這可能僅僅是: M1 my_matrix(N,P,分配) ;
這是一個微妙的區別,但是分配器是一個更爲一般的概念,我們可以使用緩存矩陣,否則對客戶端沒有意義,除非它是某種緩存,您的函數需要它們來幫助他們更快地計算結果。請注意,它不必是一般的分配器。它可能只是你預先分配的矩陣緩衝區傳遞給矩陣構造函數,但從概念上講,它可能是很好的分離出來,僅僅是因爲它對客戶端來說有點不透明。
此外,構建此臨時矩陣對象還需要注意不要跨線程共享它。這是您可能想要將這個概念推廣到一點的另一個原因,因爲像矩陣分配器這樣的更通用的東西可以考慮線程安全性,或者至少通過設計強調一個單獨的分配器應該更多每個線程都可以創建,但原始矩陣對象可能不能。
以上僅在您真正關心接口質量時纔有用。如果不是的話,我建議你用Matthieu的建議,因爲它比創建分配器簡單得多,但我們都強調使加速版本可選。
取決於。內存分配很昂貴。從本地的分配開始,並修改如果分配太昂貴 – Anycorn 2012-03-02 07:41:57
@Anycorn內存分配可能比訪問500或更多的值更便宜,並且肯定比訪問一百萬個值更便宜。 – 2012-03-02 09:05:11
@JamesKanze +1與這些操作相比,堆分配的相對效率通常是微不足道的。我正在考慮編輯我的文章,以避免完全建議優化路線。 – stinky472 2012-03-02 09:35:36