我有一个检查NSData
值的方法如下:
if (data == nil) {
//Method
}
但是尽管方法中包含了所有内容,但事实证明,超过80%的时间花在了第一行,检查data
是否等于nil
。有没有更有效的方法来做到这一点?
截图:
答案 0 :(得分:3)
这不是与nil
的直接比较。这是一行上的多个陈述。
分解问题的一种方法是划分陈述。您也可以进入实施阶段。简而言之,分析器的突出显示被误解了。
打破这个局面:
NSData * thumbnailData = self.thumbnail;
NSUInteger length = thumbnailData.length;
访问房产不会花费太多时间。
访问长度不应花费太多时间(假设这是不可变数据)。
我怀疑self.thumbnail
可能会有一些延迟加载。但是,如果深入了解实现,分析器将为您提供更多详细信息。
最后一点是可以在方法的本地解释。如果该方法不是热点并且上述方法确实不起作用,那通常意味着“当您调用此方法时通常会加载缩略图”。
答案 1 :(得分:1)
肯定没有比与nil
直接比较更快的方式来检查,或者至少你不会通过摆弄那条线来获得任何显着的性能 - 这个分析数据是不准确的。
根据我的经验,当方法(在你的情况下为-getThumbnail
)被运行太多次时,会出现这种行为(仪器'错误地指责方法的第一行)。在调用-getThumbnail
时尝试优化。
答案 2 :(得分:1)
您必须考虑经典采样型性能分析器的工作原理。
基本上,当你的程序运行时,一个计时器会熄灭,比如每100微秒,你的程序就会中断。然后,探查器检查指令指针,并根据其相对于被分析的代码段的开始和结束的值,将索引转换为整数计数器数组,并递增对应于代码地址的计数器。
但是(至少)有三件事阻止这种“完美”:
除了非常小的程序之外,每个指令都有一个计数器是不切实际的,因此代码空间会被切换成16个字节或1000个字节的间隔,具体取决于您的设置方式,并且个人计数器收集该范围内所有指令的增量。这意味着测量的“精度”与您在程序中的确切位置相比并不完美。
它在很大程度上取决于特定的处理器,但通常处理器只识别代码中某些点的定时器中断,例如采用分支和执行某些“系统”操作时,或者它可能只是等到预取缓存已耗尽。因此,探查器的定时器中断可能会“触发”,处理器可能会继续执行多个指令。
某些代码序列(例如比较和交换)可能会禁用中断,因此禁用区域内的所有活动最终都会被“责备”在紧随其后的指令上。类似地,某些类型的系统调用是以在调用期间禁用中断的方式进行的,因此,调用的全部成本将被“归咎于”紧接着的指令。