移植到Objective-C的Java代码非常慢

时间:2011-11-29 12:02:34

标签: cocoa

我想说明一个具体的例子,以了解在Objective-C中重写java代码时是否存在最佳(和最差)实践。

我已经将org.apache.wicket.util.diff.myers的Java实现移植到OSX Snow Leopard上的Objective-C(Xcode 4),但与Java版本相比,结果运行得非常慢。

性能最差的方法是buildPath,它主要是

  • 稀疏数组访问(对角线变量,此数组在方法内分配,不返回)
  • 随机数组访问(orig和rev变量)
  • PathNode及其子类的分配(具有三个属性的对象,只有属性是由数组内部使用的元素)
  • 字符串比较

Cocoa没有任何集合类可以轻松使用稀疏数组,所以我已经分配了一个带有malloc的数组,这大大改进了基于NSDictionary的第一个版本和分配用作密钥的数量的NSNumber对象。

PathNode(s)分配是使用普通语法[[MyClass alloc] init]完成的,它们不是自动释放的,因为它们被添加到NSMutableArray中(但是在将它添加到数组后立即释放)

使用[NSArray objectAtIndex:index]完成对数组的随机访问我认为(但我可能错了)将它移动到C类并不会加速。

您是否有任何想法可以提高性能,哪里可以找到瓶颈? 使用仪器74%的时间用于分配,我该如何改善分配?

编辑我已将我的实际实施提交到github,显然是alpha版本尚未准备好投放,并且不使用任何有效的objective-c构造

2 个答案:

答案 0 :(得分:2)

你有一个很好的开始。您已经分析了代码,隔离了实际的瓶颈,现在专注于如何解决它。

第一个问题是哪个分配成本高昂?显然你应该首先关注那个。

有几种有效的方法可以处理稀疏数组。首先,查看NSPointerArray,它旨在保存NULL值。它不承诺对稀疏数组有效,但@bbum(谁知道这些事情)suggests it is

接下来,查看NSHashMap,这对于稀疏集合(它是字典)肯定是有效的,并且支持非对象键(即,您不需要创建NSNumber)。 / p>

最后,如果分配确实是你的问题,有各种各样的技巧来解决它。最常见的是重用对象而不是破坏对象并创建另一个对象。这就是UITableViewCell的工作方式(以及NSCell以不同的方式)。

最后,如果切换到Core Foundation对象,您可以创建自己的专用内存分配器,但这确实是最后的手段。

请注意,10.6支持ARC(不归零弱引用)。 ARC大大提高了许多常见内存管理模式的性能。例如,在ARC下高度优化了“保留+自动释放+返回”这一非常常见的模式。 (ARC中的语言中不存在“retain”,但它仍然存在于编译器中,并且ARC比手动操作快得多。)我强烈建议您使用任何代码切换到ARC。

答案 1 :(得分:1)

您可以使用NSPointerArray类替代稀疏数组。 NSPointerArray允许null个元素。

如果您发布产生大量分配的代码,我们可能会为您提供更多帮助。

相关问题