【问题标题】:Profiler is telling me that comparison to nil is slowProfiler 告诉我与 nil 的比较很慢
【发布时间】:2012-05-26 11:17:04
【问题描述】:

我有一个方法可以检查NSData 的值,如下所示:

if (data == nil) {

//Method

}

但是,尽管方法中包含所有内容,但事实证明,超过 80% 的时间都花在了第一行,检查 data 是否等于 nil。有没有更有效的方法来做到这一点?

截图:

【问题讨论】:

  • 变量在哪里设置?我认为我们需要查看更多代码。
  • 是否有可能里面的东西只在 1% 的运行中被执行,因为数据大多是 nil,所以即使它需要更长的时间,它也几乎不会被执行并且总时间更少?
  • @Dani,+1。 @Andrew,我可以向您保证,将指针与 nil 进行比较并不昂贵。要么你做了无数次(这意味着你的问题出在其他地方,不管它多久完成一次),要么你的测量不正确或被误解。
  • 性能检测可能会令人困惑。指令指针的采样往往发生在分支点,因为这是检查中断的地方,因此在细粒度上,分支通常会被“指责”负责附近花费的所有时间。这种采样实际上只对相当大的代码块有效,而不是在逐条指令级别。
  • 错误在于认为if 上的 97% 表示法仅适用于一个语句,而实际上它适用于直到下一个突出显示的行的所有语句。

标签: objective-c ios performance profiling


【解决方案1】:

这不是与nil 的直接比较。一行中有多个语句。

划分问题的一种方法是划分陈述。您还可以单步执行您的实现。简而言之,分析器的突出显示被误解了。

分解:

NSData * thumbnailData = self.thumbnail;
NSUInteger length = thumbnailData.length;

访问属性不会花费太多时间。

访问长度应该不会花费太多时间(假设这是不可变数据)。

我怀疑self.thumbnail 中可能存在一些延迟加载。但是,如果您深入了解实现,分析器将为您提供更多详细信息。

最后一点是,它可以被本地解释为方法。如果该方法不是热点并且上述方法确实不起作用,那通常意味着“通常在您调用此方法时加载缩略图”。

【讨论】:

    【解决方案2】:

    肯定没有比直接比较 nil 更快的检查方法了,或者至少你不会通过摆弄那行来获得任何显着的性能——这个分析数据是不准确的。

    根据我的经验,当方法(在您的情况下为-getThumbnail)运行太多次时,会发生这种行为(仪器错误地“指责”方法的第一行)。在调用-getThumbnail 时尝试优化。

    【讨论】:

    • 我没有看到任何迹象表明 Instruments 错误地归咎于任何事情。
    • OP 说,以微不足道的方式更改比较会导致指责不同的行。
    【解决方案3】:

    您必须考虑经典采样型性能分析器的工作原理。

    基本上,当您的程序运行时,计时器会每隔 100 微秒关闭一次,然后您的程序就会被中断。然后分析器检查指令指针,并根据其相对于被分析代码段的开始和结束的值,索引到整数计数器数组,并增加与代码地址对应的计数器。

    但是(至少)有三件事会阻止它变得“完美”:

      1234563并且一个单独的计数器收集该范围内所有指令的增量。这意味着关于您在程序中的确切位置的测量“精度”并不完美。 1234563预取缓存已耗尽。因此分析器的定时器中断可能会“触发”,处理器可能会继续执行更多指令。
    1. 某些代码序列(例如比较和交换)可能会禁用中断,因此禁用区域内的所有活动最终都会“归咎于”紧随其后的指令。类似地,某些类型的系统调用是在调用期间使中断禁用的方式进行的,因此,调用的全部成本再次“归咎于”紧随其后的指令。

    【讨论】:

      猜你喜欢
      • 2015-10-05
      • 2022-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-22
      相关资源
      最近更新 更多