FPS

CADisplayLink allows us to register a callback processing synchronized with the refresh signal. FPS values can be displayed through a screen refresh mechanism.

Question:

  • Callbacks always require CPU idle to process and cannot collect call stack information in a timely manner.
  • Listening for screen refreshes wakes runloop up frequently, causing some loss when idle

The child thread Ping

Empty tasks are periodically added to the main thread using child threads. If the task is not executed after the specified time, it is considered as being stuck.

The problem

  • An error occurred between pings.
  • The main thread runloop is constantly woken up with some loss.

RunLoop

Based on Runloop detection, the child thread is used to detect runloop status in real time. If the execution time exceeds the specified time, it is judged as stalled.

Question:

  • Catching a stuck stack is not necessarily the most time-consuming task. However, the most time-consuming tasks have a higher probability of being captured.
  • In some complex pages, the occurrence of caton is not necessarily caused by a large time-consuming task, but by the joint action of several small time-consuming tasks. In this case, runloop detection can hardly help us solve the interface lag problem.

hook objc_msgSend

Hook objc_msgSend and objc_msgSendSuper with FishHook to insert code at the start and end of method execution to get the stack and the time taken for each method. Set a certain threshold to extract time-consuming methods.

Question:

  • Need to write assembly to hook, implementation cost is relatively high.
  • Inserted code executes more frequently. It can be optimized by some means
    • Only calls on the main thread are operated on
    • Record methods that take some time
    • The allocated queue and stack memory space is multiplexed to avoid frequent application and release.

Simple summary

Implementation costs Performance loss Value of the stack
FPS simple Screen refreshes wake up runloop frequently There is no
Ping simple The main thread runloop is constantly woken up In the
Runloop medium low In the
TimeProfiler More complicated Peg code calls frequently high