Tim*_*Tim 1 optimization performance cocoa objective-c
我最近发现自己编写了一段执行Core Data fetch的代码,然后分配了两个可变数组,初始容量等于fetch返回的结果数:
// Have some existing context, request, and error objects
NSArray *results = [context executeFetchRequest:request error:&error];
NSMutableArray *firstArray = [[[NSMutableArray alloc]
initWithCapacity:[results count]] autorelease];
NSMutableArray *secondArray = [[[NSMutableArray alloc]
initWithCapacity:[results count]] autorelease];Run Code Online (Sandbox Code Playgroud)
我写完之后再次看了一遍,有些事让我感到奇怪:我打了[results count]两次电话.结果集可能非常大(数百个,也许是一千个对象).
我的第一个问题是打破[results count]一个单独的NSUInteger,然后使用该整数作为每个数组的容量.我的问题:这种手工优化是否必要?编译器是否会识别它正在运行[results count]两次而只是保持该值而不必显式指定该行为?或者它会运行两次方法 - 这可能是一项代价高昂的操作?
类似地,程序员(特别是iPhone程序员,其中可用的内存/处理能力有限)可以手工完成其他优化,而不是信任编译器?
回答实际问题:不,Objective-C编译器无法优化远离方法发送.(嗯,实际上,有一种可能的情况:如果它确实知道接收器是零的.)
类没有办法提供有关方法行为的保证(特别是,您不能使用gcc __attribute__((const))等方法),并且编译器无法告知由于Objective-而将调用哪种方法实现C的动态性.例如,results实际上可能是一个代理对象,它在count每次调用时将方法转发给随机对象.Core Data没有特别的理由这样做,但编译器不知道这一点.
除此之外,调用的成本-[NSArray count]是微不足道的,并且除了非常人为的代码外,绝对没有办法将特定方法作为瓶颈.避免双重呼叫的习惯可以合理地被认为是值得的,但实际上担心成本或因性能原因而重新"纠正"它将浪费时间,很可能比你的程序花费更多时间来调用-[NSArray count]它使用寿命.