Xcode 时间分析器精度

3
我想知道从一个屏幕到另一个屏幕所需的确切时间,例如登录并访问下一个屏幕需要多长时间。我尝试使用Xcode时间分析器,但它没有记录所有内容。我甚至启用了“高频率”选项,但仍然觉得缺少一些东西。我现在明白了,您必须使用signposts才能实现准确性。这很有效,但是您必须将iOS版本设置为12并更改代码以添加os_signpost。是否有其他方法可以在不更改iOS版本或代码的情况下实现此目的?
您有没有其他Xcode分析工具或其他工具的建议可以提供给我这个输出?
我以为时间分析器会给我每种方法的开始和结束时间,类似于Android Studio分析器。难道我漏掉了什么?
2个回答

4

以下是一些观察:

  1. Yes, if you want to calculate the time elapsed between two points of code, signposts are a great way of doing that. And if you want to know what’s going on between those two signposts, a “points of interest” range, which you can zoom into by control-clicking. This lets you focus on the area in question:

    enter image description here

  2. I'd suggest selecting “Record Waiting Threads”. Sometimes your thread is blocked by something, and if you don’t choose this option, it won't capture samples when your thread is blocked, often making it harder to find the culprit.

    enter image description here

    (I also tend to record in deferred mode, too, to minimize the observer effect.)

  3. You said

    you have to set your iOS version to 12 ...

    Well, not quite. Sure, if you want to use os_signpost you have to do your profiling on an iOS 12 device/simulator, but you don’t have have to change the target of your app. You'd only have to wrap your logging statements in #available blocks, e.g.:

    import UIKit
    import os.log
    
    @available(iOS 12.0, *)
    let pointsOfInterest = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: .pointsOfInterest)
    
    class ViewController: UIViewController {
        @IBAction func didTapNextButton(_ sender: Any) {
            if #available(iOS 12.0, *) {
                os_signpost(.begin, log: pointsOfInterest, name: "Transition")
            }
    
            performSegue(withIdentifier: "Next", sender: self)
        }
    }
    

    and

    import UIKit
    import os.log
    
    class SecondViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            somethingSlow()
        }
    
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
    
            if #available(iOS 12.0, *) {
                os_signpost(.end, log: pointsOfInterest, name: "Transition")
            }
        }
    
        func somethingSlow() { ... }
    
    }
    
  4. If you don't like having that if #available check and you have to support older OS versions, just use kdebug:

    kdebug_signpost_start(0, 0, 0, 0, 0)
    

    and

    kdebug_signpost_end(0, 0, 0, 0, 0)
    

    You don't have nice names on your points of interest ranges, but it works in older iOS versions.

更多信息,请参见 WWDC 2018 视频使用日志记录测量性能


非常感谢您的详细解释。我有一个额外的问题。即使在代码中,构建发布应用程序时是否会自动忽略kdebug?还是我需要将其包装在#if DEBUG周围? - Vivian
使用 kdebug,你可能需要这样做。而使用 OSLog,你需要在定义 OSLog 时加上 .disabledif 逻辑,就像 https://gist.github.com/robertmryan/880d047aa0f8033924f2d7fafa06ad23 中的示例一样。顺便说一下,我不确定你是否想要使用 #if DEBUG,因为你应该总是在优化构建上进行性能分析。在调试构建中对性能进行基准测试没有什么意义。 - Rob
1
是的,您关于在优化构建上执行性能分析是正确的。再次感谢您的帮助! - Vivian

0
“我有什么遗漏吗?” 事实上没有。内置的时间分析器工具的核心功能是定位执行时间最长的方法,并让您了解它们花费时间的位置。如果您发现您可以从时间分析器中的列表到实际代码的时间分析显示,显示其中特定调用所花费的时间,那么您已经基本上找出了所有需要找出的内容。如果您想要给特定的代码片段加上括号,那就正是标志牌存在的目的,就像您所说的那样。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接