簡體   English   中英

如何在C ++中有效地管理內存/時間?

[英]How to efficiently manage memory/time in C++?

案子:

我用Java編寫了一個minimax算法,然后將代碼移植到C ++中,並保留了相同的類和方法。 然后我對C ++代碼進行了評估,直到通過將delete函數放在析構函數中(如果可能)修復了所有內存泄漏。 修復所有漏洞后,我在井字游戲中測試了該算法,然后將該代碼以相同的方式移植到C ++中。 我確定C ++版本的性能會更高,但是我驚訝地發現C ++版本在125秒內解決了100個(非隨機)游戲實例,而Java版本在30秒內解決了它們! 然后,使用系統監視器,我檢查了兩個程序的內存使用情況:測試結束時Java代碼的內存使用率大約增加了20%,而C ++版本的內存僅增加了5%。

然后,在我看來,很明顯,此delete策略可以節省內存,但會破壞時間性能,這至少在這種情況下不是我想要的。 是否有另一種刪除策略可以更好地設計軟件,從而需要較少的運行時間但允許較高的內存使用量?

malloc和delete必須做更多的工作,因為

  • 內存不是以多線程方式分配
  • 內存不會在內存中連續分配,而是分配給可用內存區域。
  • delete在當前線程中執行。
  • 對於64位應用程序,您可能會發現內存對齊是16個字節而不是8個字節,從而導致每個分配的填充量更大。

C ++中可能的解決方案

  • 不要過多地使用堆,在堆棧上的分配比Java或C ++的堆快得多,並且它是多線程的。
  • 盡可能一次分配對象塊,例如,對象數組是C ++中的一種分配,而不是Java中的N + 1。
  • 使用多線程分配器。 C ++支持多個分配器。
  • 使用競技場分配模式。 如果您的數據結構較大且包含大量節點,則可以一次分配N個節點的塊,並在釋放此類節點時構建一個空閑節點的鏈表。 您需要使用節點本身來執行此操作。 在這種方法中,整個數據結構/區域立即被釋放。

簡而言之,如果您將Java代碼直接轉換為C ++,則可能會很慢,因為這沒有利用C ++允許的所有優化,而Java卻沒有。

BTW Java 6+使用32位引用來存儲多達32 GB的內存。 如果您構建64位C ++應用程序,請查看是否可以選擇使用32位指針/引用/索引。

如果您一直在構建一棵樹(具有許多動態分配的小節點)並將其拆除,那么最適合垃圾回收的情況。 您可能想將Boehm收集器與C ++一起使用。 (Boehm的基准測試IIRC旨在顯示垃圾收集比手動分配更快,它執行的操作與此非常相似:先構建大樹,然后將其拆除。)

另外,您可以查看某種內存池。 這不是C ++的初學者技術,但也不是那么困難。 或者,不是刪除節點,而是將它們放到空閑列表中,以供以后回收。 (分配時,您首先查看空閑列表,只有在它為空的情況下才調用new 。)或將兩者結合。

暫無
暫無

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

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