2009-11-25 25 views
0

我很喜歡STL。它使得編碼算法非常方便,因爲它提供了parition,find,binary_search,iterators,priority_queue等所有基元。另外,您根本不必擔心內存泄漏。運算符超載的性能損失是多少STL

我唯一擔心的是運算符重載的性能損失,它是獲得STL工作所必需的。 爲了比較,我認爲它依賴於==提供了所需的語義。如果我們將類添加到容器中,我們需要重載==運算符。

爲了這種便利,我輸了多少效率?

關於內存泄漏的另一邊的問題:

  1. 可以使用STL容器時,內存泄漏不會發生?
  2. 在Java中可以發生內存泄漏嗎?
+4

當然,內存泄漏可能發生在Java中 - 請參見:http://www.ibm.com/developerworks/library/j-leaks/ – schnaader 2009-11-25 22:42:13

+2

重載操作符基本上是一種方法。 – 2009-11-25 22:51:56

+0

尼斯鏈接@schnaader。希望我可以給你+1評論。 – 2009-11-25 22:52:09

回答

10

在泛型類型上使用stl algortithms時,必須以某種方式提供比較邏輯。運算符重載對任何其他函數都沒有性能損失,並且可以(像任何其他函數一樣)內聯來消除任何函數調用開銷。

許多標準容器和算法也使用std::less,因此默認使用<而不是==

標準容器本身不會泄漏,但您可以使用它們來保存不需要清理它們「擁有」的內存的對象(如指針)。

在java中很難泄漏內存,但這並不意味着你不會因爲沒有良好的對象所有權語義而陷入麻煩,並且這並不意味着你無法使用所有可用的內存並崩潰。

4

我會將C++答案留給以前的海報,但100%是的你可以在Java中進行內存泄漏。除非你有一些好的內存分析工具可以查看,否則它往往很難找到。一般情況下,當你重複實例化對象時,會發生自動垃圾回收語言(例如Java,Python等)中的內存泄漏,但是當你完成它們時,不要清理它們(例如,調用「close」一個數據庫連接)或B.繼續保留指向它們的其他對象(例如哈希表),以便自動垃圾收集器永遠不會垃圾收集它們。

如果你的應用是什麼,你認爲應該是一個穩定的狀態,你會得到其中的一個:

http://java.sun.com/javase/6/docs/api/java/lang/OutOfMemoryError.html

你在一些有趣的debuggin;)

+0

也許這是太多的C++傾斜,但是如果內存被在應用程序中仍然有引用的對象使用,它真的是內存泄漏嗎?在這種情況下,內存仍然可以(理論上)從應用程序中的對象中找到。 「真正的」內存泄漏是對某些內存的最後引用實際上已被銷燬的地方,所以根本沒有指向應用程序內存的指針。 – 2009-11-25 22:57:02

+0

但效果是一樣的。 – UncleBens 2009-11-25 23:01:57

+0

我認爲定義在自動垃圾收集語言中有點改變......對我來說,這些語言之一的內存泄漏是程序員爲防止垃圾收集器清除對程序員完成的對象的引用所做的任何事情並期待被垃圾收集。自動垃圾收集器足夠聰明,可以清理不再有任何其他對象引用它們的對象。要在Java中保存內存,仍然必須有活動引用來放置對象。 – 2009-11-25 23:19:01

1

由於操作符重載只是簡單地導致一個函數調用,而你必須編寫一個函數來完成這項工作,開銷爲零。運算符重載只是一種方便,所以您可以執行x == y而不是x.equals(y)或x < y而不是x.compaterTo(y)。編譯器本質上產生如下內容:x。==(y)或x。 <(y)(不會編譯,但你明白了)。

1

「懲罰」實際上是一種獎勵。

讓我們看看最典型的算法,排序。 C沒有運算符重載。結果,qsort接受一個函數指針。每個比較使用一個間接函數調用(在運行時)。 C++確實有操作符重載。對於std::sort,每個比較是直接調用(由鏈接器確定)或內聯(由編譯器)。這是非常有效的。 std::sortqsort快6倍並不罕見。

通常,運算符重載使得爲某個類型表達「默認」函數要容易得多,其方式可以被其他代碼和編譯器利用。替代品效率遠低於其他產品。他們要麼依靠宏(其傷害程序員)或它們依靠函數指針(這傷害了優化和CPU)。

1

我唯一擔心的是操作符重載的性能損失是必要得到STL工作。爲了比較,我認爲它依賴於==提供了所需的語義。如果我們將類添加到容器中,我們需要重載==運算符。

這是不存在的。你的重載操作符被實現爲一個函數調用。如果你沒有重載操作符,你需要定義一個函數來代替。所以性能是正好相同,只是一個更乾淨的語法。