2011-11-29 47 views
4

我想說明一個具體的例子,以瞭解在Objective-C中重寫java代碼時是否存在最佳(和最差)實踐。移植到Objective-C的Java代碼非常慢

我已將OSE org.apache.wicket.util.diff.myers的Java實現移植到OSX Snow Leopard(Xcode 4)上的Objective-C,但結果與Java版本相比運行速度非常慢。

的方法,與最壞的性能是構建路徑,它主要做

  • 稀疏數組訪問(對角線變量,此陣列被分配內的方法和不返回)
  • 隨機
  • 數組訪問(原稿和rev變量)
  • 分配PathNode的及其子類(具有三個屬性的對象,只有屬性是內部使用由數組的元素)
  • 串比較

可可還沒有任何集合類,所以我分配使用malloc數組與稀疏數組輕鬆地工作,這大大提高了基於NSDictionary中和分配的NSNumber的對象數不勝數的第一個版本中使用的關鍵。

(多個)分配使用正常語法[[MyClass alloc] init]完成,因爲被添加到一個NSMutableArray(但它添加到陣列後立即釋放)

到陣列隨機存取完成它們不會自動釋放的PathNode使用[NSArray objectAtIndex:index]我認爲(但我可能是錯的),將它移動到類似C不會加速。

你有什麼想法來提高性能,哪裏可以找到瓶頸? 使用儀器74%的時間花在分配上,我該如何改進分配?

編輯我已提交實際實施github,顯然是一個alpha版本沒有準備好生產,不使用任何有效的Objective-C構建

+0

嘗試按照本文所述使用「堆棧對象」:http://mikeash.com/pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c。 html 它們非常有限,但是如果您需要buildPath例程中的數據,只有這樣才能減少分配時間。 – viggio24

+0

感謝「堆棧對象」幫助我刪除malloc/free,但主代碼依賴(並返回)一個包含數組的對象,它們被分配到循環中。我已經提煉了我的問題 – dafi

回答

1

您可以使用NSPointerArray類作爲替代爲你的稀疏陣列。 NSPointerArray允許null元素。

如果您發佈生成大部分分配的代碼,我們可能會幫助您更多。

+0

我已經在github上提交了https://github.com/visualdiffer/DiffUtils並更新了我的問題帶有性能瓶頸的課程是https://github.com/visualdiffer/DiffUtils/blob/master/ src/DiffUtils/myers/MyersDiff.m – dafi

2

你是一個很好的開始。您已經對代碼進行了剖析,將實際的瓶頸隔離開來,現在將重點放在如何解決這個問題上。

第一個問題是哪個分配代價高昂?顯然你應該首先關注那一個。

有幾種有效的方法來處理稀疏數組。首先,看看NSPointerArray,它被設計爲保存NULL值。它不承諾是有效的稀疏數組,但@bbum(誰知道這樣的事情)suggests it is

接下來,看看NSHashMap,這對於稀疏集合(它是一本字典)當然是有效的,並且支持非對象鍵(即不需要創建NSNumber)。

最後,如果分配真的是你的問題,有各種技巧來解決它。最常見的是重複使用對象而不是破壞對象並創建另一對象。這是UITableViewCell如何工作(和NSCell以不同的方式)。最後,如果切換到Core Foundation對象,則可以創建自己的專用內存分配器,但這確實是最後的手段。

請注意,10.6支持ARC(沒有調零弱引用)。 ARC通過大量常見的內存管理模式大幅提升了性能。例如,在ARC中高度優化「retain + autorelease + return」的常見模式。 (「保留」在ARC語言中不存在,但它仍然存在於編譯器中,ARC比手動更快)。我強烈建議您使用任何代碼切換到ARC。

+0

我正在使用Snow Leopard,但SL的XCode 4不支持ARC – dafi

+2

@dafi是; Snow Leopard可以運行使用基於Lion構建的ARC的程序,但Snow Leopard上的Xcode無法構建使用ARC的程序。它缺少一個它需要的庫。 –