IOS Performance Optimization: Instruments Use combat
Instruments is used to analyze the performance of the entire application. Discover many interesting points, as well as performance optimization and some techniques for analyzing performance consumption, summarized below.
Instruments Use Tips
About instruments official has a very useful user to use guide, of course if not accustomed to the official English can be found here in the text translated version PDF see. Instruments is indeed a very powerful tool, It is extremely convenient to collect data about the performance and behavior of one or more system processes, and to keep track of data over time. There are also extensive collections of different types of data. The basic use of instrument tools is not to be described in detail.
1. Overview
The tool can be started by Product->profile in the Xcode toolbar, and the following start interface is as follows:
instrument overview [via by Chenkai]
When you click on the time Profiler application starts running. You can get the entire application run consumption distribution and percent. In order to ensure that the data analysis in the unified use of the scene is really implemented there are the following points to note:
When starting an application profiling, be sure to use the real machine, the emulator running on the MAC, while the CPU on the MAC is often faster than the iOS device. On the contrary, the GPU on the Mac is completely different from the iOS device, and the simulator has to simulate the device's GPU at the software level (CPU), which means that the GPU-related operations are running slower on the emulator, especially when using Caeagllayer to write some OpenGL code. This results in the performance data of the simulator and the user's real-machine performance.
Another important thing before you start profiling is that the application must run to publish the configuration Instead of the Debug configuration .
When the publishing environment is packaged, the compiler introduces a series of optimizations that perform high performance, such as removing debug symbols or removing and organizing the code. Another iOS introduces a "Watch Dog" [watchdog] mechanism. In different scenarios, the watchdog monitors the performance of the application. If the runtime is exceeded, the watchdog will force the process to terminate the application. Developers can crashlog see the corresponding log. But Xcode disables "Watch Dog" under Debug configuration.
The following figure is two debugging methods, in general, we will use the former debug CPU health
2.Time Profiler
Select Time Profiler to start.
The time profile tool is used to detect application CPU usage. You can see that each method in your application is consuming CPU time. Using a large number of CPUs is not necessarily a problem. The path of the weather animation [similar to heavy rain] on the different scenes in our client is very high on the CPU, The animation itself is also a very demanding and resource-intensive task.
Click on the record to start running.
Time profile Analysis interface [via by Chenkai]
This is often the case when we first get the analysis data:
performance data [via by Chenkai]
This shows the complete path to the execution code, where the system and the application itself are completely kneaded. The actual code execution time and the code path actual location of the application in which we are concerned are not seen at all. Simple way to quickly tick right call tree separate Thread and hide System libraries two options [explain option effects later]:
Performance data after splitting [via by Chenkai]
You can see direct paths that can be seen directly from each method invocation of the application, eliminating the system-related methods and the reverse call tree path. Refreshing a lot. If this is not intuitive enough, choose any time-consuming method branch [here Select Weatherviewcontroller Viewdidload] Double-click Enter to see:
Code & Time Consuming details
You can navigate directly to the Viewdidload code, and you can see visually that the change method will take time to cut down in other ways. Similar to [self loadcityweatherscroollerview] it takes 121x, X is both time-consuming units here for Ms milliseconds. Of course, if you find a problem directly in instrument, it's inconvenient to change, You can directly click on the top right Xcode button to directly locate the Xcode corresponding call method entry. It's easy to quickly locate the most CPU-intensive method for your code. You can also turn on the Xcode to quickly modify and rerun the profile to see how long it takes to change it. Simple and convenient.
There is a need to do a description of the right call Tree option [official User Guide translation]:
separate by thread: Threads detach, only so that the most CPU-hogging threads can be seen clearly in the call path.
Invert calls tree: tracks stack information from top to bottom. This option can quickly see the method call path deepest way to occupy CPU time consuming, such as Funca{funb{func}, check the stack to c->b-> A the deepest C of the call level shows the outermost.
Hide Missing Symbols: If dSYM can't find your app or call the system framework, then the table will see that the call method name can see only 16 values, check this option to hide these symbols, easy to simplify the analysis of data.
Hide System Libraries: This is even more useful, and the time-consuming call path after the check will only show the app's time-consuming code, Performance analysis generally we compare the time consuming of our own code rather than the system. Basic is required. Note that some code time consuming is also included in the system hierarchy, which can be useful for comparing the execution path before and after the check.
about other methods no longer repeat.
Performance Analysis & Code Optimization
Our performance optimization is focused on the following two usage scenarios:
A: The first time the application starts to enter the weather home page.
B: From the background cut to the front of the weather home occupancy time.
Until the profiling data has been obtained, it is thought that the first time to start is a major waste of appdelegate on third-party framework initialization [similar to weibo&wechat related SDK initialization calls]. When we get the actual performance data time consuming ratio, we find that this is not the case:
Startup time consuming
As you can see, the application startup initialization work will be mjappdelegate in the following two ways: Willfinishlaunchingwithoptions and Didfinishlaunchingwithoptions, The initialization of the third-party framework is mainly done in willfinishlaunchingwithoptions. and the actual time taken up is very small. The basic can be negligible.
And we want to optimize two startup time scenarios, different from. The first entry needs to go through the novice tutorials, add cities, request city data, parse data, initialize the weather homepage UI elements, and load scene animations. When entering from the background, the weather data is parsed from the local storage dt file, the weather homepage UI element is initialized and the weather animation is loaded.
1.NSDateFormatter Problems Highlight
Focus on this analysis application startup & weather home time consuming. In AB Two scenes were found to load the first element found the following problem:
NSDate (Timeago) Getdatestrbytimezone time consuming
Continue tracking Discovery:
NSDate Time consuming
It is time-consuming to acquire time zone corresponding time when loading Mjlinechartview and Tendencychartview in AB two scenarios. And time-consuming is mainly in Getdatestrbytimezone this method call.
The average time to create a NSDateFormatter object is about 33MS The average time to set the 3 properties of NSDateFormatter is about 30ms. Because of the home 24-hour weather and the forecast for the next few days. You need to traverse the data in a for loop, causing this method to not be repeated repeatedly, and then consuming a stack of times.
In response to this problem :
The NSDateFormatter object itself is very slow to initialize, as is the case with Nscalendar. However, it is unavoidable to use them in some usage scenarios, such as JSON data parsing. Using this object also avoids the performance overhead of its performance overhead, The generally better way is to keep the object initialized only once, by adding a property (recommended) or by creating a static variable, and being reused more than once. It has to be mentioned that setting a NSDateFormatter property speed is almost as slow as creating a new instance object.
For nsdateformatter time overhead, it is necessary to avoid using it to process multiple date formats. Of course, for date format processing if you need to improve more speed, you can directly use C, you can use a Third-party library to circumvent this problem.
2.UIImage Caching Trade-offs
UIImage use
In main thread, it is found that the ratio of image IO overhead and time consuming in different animation scenes is not the same, and the uiimage element can occupy a certain proportion when it is more overall. Memory overhead is also significantly higher.
There are generally two ways to load pictures uiimage:
A:imagednamed initialization
B:imagewithcontentsoffile initialization
The difference is that the image is cached in memory when the picture is successfully imagenamed by default, and this method looks up and returns a picture object in the system cache with a specified name. If the corresponding picture object is not found in the cache, the picture is loaded from the specified place and the object is cached. and returns the Image object. Imagewithcontentsoffile only loads pictures and does not cache them.
A large number of imagenamed methods will add overhead CPU time to do this without needing to cache. When the application needs to load a larger picture and use one-time, then there is no need to cache the picture, with Imagewithcontentsoffile is the most economical way , this will not be because the uiimage elements in more cases, the CPU will be dispersed in the unnecessary cache of excessive time wasted.
Use scenarios need to be programmed, should be based on the actual application of the scene to distinguish, although uiimage small, but the use of elements more problems will be highlighted.
3. Weather Home load Policy
Comparative analysis of performance data in AB Two scenarios shows:
Weather Home Weatherview Initialization time has been 300ms-450ms between, occupy a large part of the home page. and always fixed overhead. Occupies one of the main Thread3 points.
And the user enters first see is the weather first upper part:
The bottom half needs scrolling to see the lower part. And not necessarily trigger:
And now the entire home view initialization and update all put to the main thread to do. of which Weatherinfoview The Updateallinfo method update takes the longest. More view means more rendering, which means more CPU and memory consumption, for our weather home in the uiscrollview inside nested a lot of view is so.
In this case, do not load too many operations on the main thread. Uikit rendering, user input response needs to be done on the main process. The main thread is accidentally block or the load response time consuming too much will affect the user experience. And for resource consumption is too large operation, processing principle is to minimize the main thread CPU footprint, will work " Move away from the main thread and do not block the main thread. Something like local io is completely moved to another thread.
During the debugging time Profiler process, it is possible to block the main thread even if it takes up a very small amount of CPU time (if you see the data in Times Profiler). disks, networks, Lock, Dispatch_sync, and sending messages to other processes/threads block the main thread. Time Profiler can only detect a stack that consumes too much CPU, but it cannot detect these IO problems. It's weird. In system trace, a call that has a very low CPU timer, but a very high wait, indicates that the main thread processing i/ O has seriously compromised the performance of the app, this time thinking about optimizing the operation.
And for us to apply the home page UI multiple view, in the load strategy can be used for synchronous loading of multithreading, only the upper half part of the main thread loaded, You can start a thread to load synchronously at the same time. This can greatly reduce the group thread initialization and update time, when the first page initialization has been rendered is, the second half of the fact has been another thread processing finished.
In addition, for a single view try not to viewwillappear time-consuming operations, viewwillappear before the view display is called, for efficiency reasons, in this approach do not deal with complex and time-consuming things; you should set view in this method only The display properties such as the background color, font, and other simple things. Otherwise, the user will obviously feel the view is slow to show.
4 : Apply first load Time
To apply the first boot load operation:
The first load sits on the following operations:
A: Linking and loading: You can display the DYLD load storage function in time profile, the library is mapped to the address space, and the binding is completed and statically initialized.
B:uikit initialization: If the applied root View controller is implemented by Xib, it will also be initialized at startup.
C: Apply callback: Invoke Uiapplicationdeleagte callback: Application:didfinishlaunchingwithoptions.
D: The first core animation call: In the Startup method-[uiapplication _resportapplaunchfinished] Call Ca::transaction::commit to achieve the first frame of the painting.
Application startup methods in the first load willfinishlaunchingwithoptions and didfinishlaunchingwithoptions only do the necessary operations for the first start of the application, but for _dyid_ Start the operation of the library framework function. Unnecessary framework do not link to avoid time consuming for first load.
Summary as above. Many local code calls and the underlying mechanism to see is not particularly clear, collation summary on the optimization of the part is limited, such as on the only for your reference. In addition, instruments is really a tool for analyzing code. No Third-party tools are available to replace it.