"General Principles of Optimization" for iOS Performance Optimization (Performance optimization is very important, why are you all useless?)

Because I have done some optimization work in the iOS development process, I have some superficial understanding of iOS performance optimization, and I always want to summarize my experience briefly.

As the first article in this series, I'm going to summarize some general principles in iOS optimization. Because I think whether it is optimization of list fluency, optimization of startup time or optimization of other aspects, there are some common principles. Only by mastering these general principles can better optimization be done. Give us specific details. The optimization task points the way and lets us take less detours. Later, if time permits, I may write about list fluency, startup time, and memory optimization.

As a developer, it is very important to have a learning atmosphere and a communication circle. This is my iOS communication group: 638302184, whether you are a novice or a big cow, welcome to join, share BAT, Ali interview questions, interview experience, and discuss technology , Let's communicate, learn and grow together!

In the first "General Principles of Optimization". I have summarized five general principles of optimization, including not to over-optimize in advance, to find performance bottlenecks, to balance between different performance indicators, to understand the underlying operating mechanism of optimization tasks, and to have a technical support system. Time is not limited to performance optimization, it will spread to other related fields, and some extended fields will be briefly discussed, hoping to have some inspiration for readers. The following is the main content of the first article.

1. Don’t over-optimize in advance

1. This principle includes two traps that need to be avoided in the process of optimization, namely pre-optimization and over-optimization. Advance optimization refers to considering performance optimization as an important task in the initial stage of development. On the basis of no actual data indicators, some blind optimization work is done in advance for performance.

Of course, this view may be controversial, because in some development fields, some performance indicators have a high probability or even inevitable performance bottlenecks based on historical experience. Therefore, performance issues need to be considered at the early stage of the architecture. Therefore, if the idea of ​​"don't optimize ahead of time" is promoted to all development fields, I think it may not be appropriate.

But if you constrain this point of view in the field of iOS development, I personally think it still holds true. Because the performance of iOS platform devices is generally better at the current stage, Apple has made a lot of optimizations in terms of performance both at the hardware level and at the system level. So I don't think the performance aspect is the primary consideration in iOS development. Compared with performance, I personally think that in the initial stage of iOS development, the following aspects are more important and need to be considered first.

2. The first thing to consider is the choice of architecture. The architecture here refers to Native architecture, web architecture, native and web hybrid architecture and cross-platform architecture. My personal opinion here is that the web architecture should be avoided as much as possible. From Facebook's early failure experience, it can be seen that there are indeed many performance and experience problems compared with native.

Even big manufacturers can't completely improve the problem of webview, let alone us. However, in some application scenarios that have more urgent needs for dynamism than user experience, the web architecture can be selected. For example, everyone has been complaining about a certain railway ticketing software. The advantage of the Native architecture is that it has a good product experience and is friendly to the technology stack of most iOS developers. The disadvantage is that some dynamic solutions cannot be used due to Apple's strict restrictions on hot updates.

The native and web hybrid architecture is mainly based on the native architecture. In some scenarios with very strong operational requirements (such as e-commerce and other scenarios), some modules are developed using web, so that the native architecture can be used in most scenarios of the app to ensure The user experience also meets the dynamic needs of some scenarios. The cross-platform architecture mainly reduces the cost of multi-terminal development, and uses a set of codes to complete the development of iOS and Android platforms. Currently, the mainstream frameworks include ReactNative, Weex, and Xamarin.

The vision of these cross-platform architectures are very good, but in the actual use process, I personally feel that the current stage is not more labor-saving than using the Native architecture, and there will be many known and unknown pits. Of course, as a new technology, we should continue to develop mentality, but it also needs a comprehensive evaluation when using it, especially as an application that may have a long life cycle, whether it is using an unofficial recommended development architecture or an open source library, if it is not maintained in the later stage, your team is It's not that you have the strength to pick up the disk. If you can't, it is safer to use the technology stack officially recommended by Apple.

3. The second thing to consider is the choice of development language. In fact, after choosing the architecture, the range of optional development languages ​​is narrowed down to a few. And it is not difficult to choose in actual project development, because the technology stack of the team developers almost determines the development language used. If a language that is unfamiliar to most team members is used, I believe that even the chosen language is overwhelming in many aspects. Because of the advantages of sex, the progress of the project will not be very smooth.

But excluding the factors of the team's technology stack, different development languages ​​do have their own advantages. Everyone knows that in the iOS development process, if the Native architecture is used, the official development languages ​​are objc and swift. objc is the official recommended language for early iOS development. The advantage is that it is dynamic, very flexible, and can implement many "black magic". The disadvantage is that the syntax is a little weird (of course, for iOS developers, it's not weird after using it for a long time), and the other is The support for some advanced language features is not very good (remember when I first used objc to develop iOS applications, because of some special requirements.

Since objc does not support namespace, it caused a lot of trouble to the team). Swift is Apple's main development language in recent years. It absorbs the advanced features of many other languages ​​and is relatively easy to use. Regarding the specific technical details of the two development languages, if you are interested, you can check some information for yourself. Although Apple has been pushing swift, but currently in the domestic iOS development field, because some mainstream apps with a large user base were written using objc before the emergence of swift, and most of them have undergone several years of version iteration, coupled with the early rise of swift ABI It requires a lot of work to be unstable and upgrade between versions, and there are some problems of mixing swift and objc, so that most mainstream apps in China still use objc as the development language.

In some start-up companies or new projects, only some developers use swift. Of course, if you take a long-term view, the future must be the world of swift. The decline of objc in the annual language rankings in the past two years also confirms this. a little. In addition to the officially recommended objc and swift, if you use other architectures such as cross-platform, you can also use languages ​​such as js, c#, etc. If you are interested, you can learn about it yourself.

4. What needs to be considered again is the choice of specific code architecture in the development process. Here we only briefly talk about the choice of code architecture under the Native architecture. At present, the commonly used architectures in iOS development include MVC, MVVM, VIPER, MVP, etc. Regarding these structures, there are many introductions on the Internet. If you are interested in the specific details, you can check them yourself. Here I just want to add that when you learn and practice, don't blindly follow new technologies. For example, MVVM and other architectures may not be much better than MVC, and MVC may not be an outdated framework. Be aware that many of the extensibility and decoupling lines brought by new architectures are achieved by introducing layers of indirection, which may come with more glue code and more complex code structures. I hope you can choose the most suitable code structure for your team and project according to the characteristics of the project and the situation of the team.

5. In addition to the three points mentioned above, there are some other key points that need to be considered at the beginning of the project, such as how to achieve a unified code style within the team? How to select some key technologies? How to ensure that the code structure is clear, simple, and scalable. Performance issues can be considered later in the project, and it is too late to optimize if there are obvious performance issues. For example, at the beginning of the project, we intuitively felt that a certain module might have performance problems, so we blindly used multithreading instead of analyzing the specific problems according to the actual situation. It will cause the program to be complicated and prone to thread safety problems.

Over-optimization refers to excessively increasing system complexity and maintenance costs in order to optimize performance, making the development cycle longer. Although it may bring a certain improvement in performance, compared with these shortcomings caused by over-optimization, it is obviously worth the loss.

6. In the process of work, the author found that many students are prone to fall into the trap of over-optimization in the process of performance optimization. For example, in this simple setting interface, there are only a dozen static cells in total. If you consider rounded corner performance, off-screen rendering, image caching, height caching, asynchronous rendering and even caching layout information, you will undoubtedly fall into the trap of over-optimization. , In this application background, simple and fast implementation of functions is the first priority. In the current development framework and platform of Apple, generally if there is a performance problem, in my actual experience, most of the problem lies in the business logic, so if you encounter a problem, you first need to find the problem in the business logic, some excessive Limit optimization is completely unnecessary.

In fact, not only performance optimization, I found that many students are over-designed everywhere in their daily development. For example, the trap of design happy in design patterns. When many beginners first learn design patterns, they are very obsessed with the power of design patterns to decouple and expand the code when they solve different problems. In the development process The Central Committee is constantly thinking about what design pattern should be used. The result is a lot of over-design. In fact, in the process of writing code, if we can follow the basic SOLID principles, we can write high-quality code in most cases.

 

2. To find the performance bottleneck

1. Before optimizing, you must first find out which performance bottlenecks are, and solve them one by one according to the severity of performance. Don't optimize blindly, otherwise it may take a lot of effort in the end, and the optimization may only be a small part of the performance loss. I think this principle is particularly important, because I have encountered many situations in my work, including myself, that do not search for performance bottlenecks and rely on subjective guesses for performance optimization. In the process of finding performance bottlenecks, you also need to pay attention to the following issues.

2. Don't make subjective guesses, let the performance evaluation data speak.

This is very important. Always remember to speak with facts. Don’t think that the time complexity of the algorithm used by a function is O(n2) and think that there will be performance problems. You have to spend a lot of effort to optimize to O (n*logn), but you may only have dozens or hundreds of input data, even O(n2) will not have much performance problems. Don't think that a method only calls a simple get method of the system library, there will be no performance problems, but this get method may contain some very time-consuming operations (such as disk IO). Therefore, when encountering performance problems, we must not rely on subjective guesses, run the performance data on the spot, and let the data tell us where the performance bottleneck is.

3. Use appropriate performance evaluation tools.

For the performance optimization of the development version, the instruments provided by Xcode are definitely the best tool for finding performance bottlenecks. The instruments have a wealth of performance evaluation tools, including the commonly used Core Animation, Time Profiler, Leaks, and Allocations. These tools have provided me with very convenient functions in analyzing function execution time, fps, and memory. Note when using instruments: use a real machine, not an emulator. The simulator's CPU is much faster than an iOS machine, so CPU-related operations will be faster on the simulator. Because the GPU of the Mac is different from the GPU on the iOS device, the simulator needs to simulate the GPU on the iOS device through software on the CPU, so GPU-related operations will be slower. Therefore, if the simulator is used for performance optimization, the inconsistency between the performance of the evaluation device and the real user device will lead to a great reduction in the optimization effect. Memory is an exception here. When doing memory optimization, there is generally little difference between using an emulator and a real machine. You can use the emulator to optimize memory.

Use the Release configuration instead of the Debug configuration, because the compiler will do some optimizations to improve performance when releasing the package. Your own engineering code may also be optimized under release, such as removing log information and some debug functions. What we care about is the performance under release, because the user also uses the release package in the end.

Therefore, when testing, you must remember to perform it under the release configuration. When instruments perform performance evaluation, the default is to perform under the release configuration. However, the optimization in the engineering code requires your own attention. The author has paid a lot for this, because I did not pay attention to some debug functions in the engineering code, which led to the mistaken belief that the dynamic library was the culprit affecting the startup time during the optimization process, and I spent a lot of effort to change the dynamic library to static. Library, wasted a lot of time.

We want to use a relatively poor machine for evaluation, because we need to ensure that our application also performs well on a poor machine. If conditions permit, it is best to cover multiple models. Unlike our traditional understanding, newer models do not necessarily have higher performance. For example, iPad3 is worse than iPad2 in animation and rendering performance.

It is necessary to cover different system versions, because on the iOS system, the higher the system version, the generally poorer performance of the same machine, so if you only cover the lower version of the model, the performance on the higher version may be unsatisfactory. .

In addition to using instruments, you can also use logs and other methods to find performance bottlenecks.

For online apps, the tool to find performance bottlenecks is mainly Application Performance Management (APM). At present, major companies basically have their own APMs, mainly for performance monitoring and early warning of online apps. Because in the development and testing stages, due to the relatively limited number of users, it is difficult to cover all business scenarios. After the app is released, the performance of a large number of users during use will bring more comprehensive performance evaluation data to our app. Therefore, the performance monitoring of online apps is very important.

To focus on the key, have a purpose. Find the top N problems with high performance loss, and solve them according to their importance and difficulty of solving, so as to spend the least energy and solve the largest problems.

Third, it is necessary to balance between different performance indicators to achieve the overall optimal

1. When the performance bottleneck has been found, the method to solve the performance problem requires a specific analysis of the specific problem, and it is necessary to balance between different performance indicators to achieve the overall optimum.

This requires us to have an overall awareness. App performance can be divided into many categories, and different performance indicators have different effects on user experience. For example, fps mainly affects the user's sliding experience, page loading time and application startup. Time affects the user experience in terms of waiting time. In the process of optimization, we must keep in mind that our goal is to hope that the overall experience of the app is optimal, rather than the optimal performance index of a single item.

2. There may be a positive correlation between different optimization indicators. For example, the time-consuming of a large number of functions in the sliding process is optimized, which improves the fps performance and may reduce the power consumption of the app. At the same time, different optimization indicators may also be negatively correlated and mutually restrictive. For example, if too much cache is used for fluency, it will lead to a decrease in memory performance, and even lead to being killed by the system due to memory warning. This undoubtedly affects the overall experience of the app. caused a negative impact. Therefore, in the actual optimization process, we need to repeatedly weigh the pros and cons and trade-offs to achieve the best overall performance.

Fourth, to understand the underlying operating mechanism of the optimization task

1. If you do not understand the underlying operating mechanism of the optimization task, it may be difficult to achieve better optimization results.

For example, when doing startup time optimization, if you don't know that the startup time of the app in iOS is composed of two parts of time before main and after main, if your app is because the part before main function takes up too much Startup time, you may spend a lot of energy to optimize the time after main but not achieve a good optimization effect.

If you don't know the operation mechanism of the app startup process, you can't know to check whether too many custom dynamic libraries are linked or go to the load function to confirm whether there are time-consuming operations, etc. And when doing fps optimization, if you don't know what the underlying cause of the freeze is, what steps a view goes through from creation to display, and what roles CPU and GPU play in this process, it's difficult to achieve smooth Slippery smooth? When doing memory optimization, it is difficult to optimize memory if you don’t know what types of memory are divided into, the different memory limit mechanisms of the system for apps and different types of extensions, and what actions the system will take if the limit is exceeded, etc. Okay. Therefore, only by deeply understanding the underlying mechanism can better targeted solutions be proposed.

2. In fact, not only in performance optimization, in many cases during the development process, understanding the underlying principles will make you more efficient and easier to solve various problems encountered. Here I am sharing an experience that impressed me a lot. I remember that once when developing a certain function, I needed to use the level db database. During the unit test during the development process, I found that the local storage file of the level db was getting bigger and bigger in the process of continuous deletion and writing. Even reach 1G size. At that time, the first impression was that there was a problem in use, so the upper-level business logic searched for the problem, but after a long search, no problem was found. But if I use level db to learn more about its underlying implementation principle and the principle of LSM (Log-Structured-Merge Tree), I will not think it is a bug when I encounter this problem, nor will it A lot of time wasted doing useless work. Therefore, it is recommended that you do not complain that the daily work is too simple and boring, and dig some deeper things in the development process, which will not only deepen the depth of your technology, but also greatly improve your coding efficiency.

Fifth, there must be a technical support system

1. Performance optimization cannot be done once and for all, and I personally think it is a protracted battle. Not only do you need to be able to do special optimization in a certain period of time, but also to make good logistical supplies to fight a protracted war. In order to keep the app performing well for a long time, it is not only necessary for developers to have good development skills. Some technical support and systems are also needed. Below are just a few that I can think of.

2. There must be a good test guarantee. The test guarantee here refers not only to the manual testing of testers, but also to the automated testing that is needed. It is necessary to establish special automated tests for different performance indicators, and establish a complete set of automated test systems from timing running tests to outputting test results, which can provide solid data support for performance assurance.

3. Introduce the online access system for key performance indicators. In the development phase, in order not to bring the code with performance problems online, indicators such as startup time, FPS, and installation package size can be used as key indicators, and automated tests are performed before going online. If the indicators do not meet the standards, they are not allowed to go online.

4. Use APM to monitor online apps and discover online performance problems. There is a timely early warning mechanism, which can solve online performance problems at any time.

5. During the development process, the code needs to have a design for performance assurance. For example, reusable high-performance controls can be designed, so that other developers can simply reuse when developing similar functions, which not only improves performance, but also greatly saves development time. For example, in order to prevent the app from loading more and more services at startup as the version iterates, resulting in slower startup, you can design an App launcher, and put these tasks on the main interface after loading is completed, and execute them in the group. A rigid specification is formed among developers. Any services that are not necessary during the startup period should either not be executed, or should be placed in the callback of the main interface of the launcher when the loading is completed.

Doing some technical sharing on performance optimization on a regular basis can not only improve the development skills of the students in the group, but also activate the technical atmosphere in the group.

The above summary of the general principles of iOS performance optimization, I hope to give you a little inspiration. Many of the ideas may be immature, and I hope everyone can criticize and discuss with each other and make progress together.

As a developer, it is very important to have a learning atmosphere and a communication circle. This is my iOS communication group: 638302184, whether you are a novice or a big cow, welcome to join, share BAT, Ali interview questions, interview experience, and discuss technology , Let's communicate, learn and grow together!

 

The article comes from the Internet. If there is any infringement, please contact the editor to delete it.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325481384&siteId=291194637