Translation: Code Performance Adjustment Performance Tuning of code the http://www.newlc.com/performance-tuning-code application runs properly and can execute all the tasks required by the user or the customer, and does not mean that the program is perfect in any way. Using performance analysis tools, such as profiler, we can understand how the program runs internally, in terms of speed, memory usage, and power usage. There are many problems that can reduce the performance of your application. Below I will list some of them:
- [Question 1: DLL usage optimization]
In Symbian, there are two types of Link Libraries: static interface DLL and multi-state interface DLL. Normally, the static link between applications and many DLL files depends on the usage of these DLL files. However, loading all dependent DLL files into the memory will reduce the application performance, this is because the static dependency of the application or service program has a great impact on the free memory. By dividing logical functions into dynamically installable components, the static dependency is minimized.
void RuntimeLoadDllL(){RFs fileSession;User::LeaveIfError(fileSession.Connect());TFileName dllName; If ( SomeCondition ){.......dllName = KDllNameOne;} else{.........dllName = KDllNameTwo;}LoadDllL(dllName); .....................fileSession.Close();}void LoadDllL(const TFileName& aLibName){RLibrary lib;User::LeaveIfErrorlib.Load(aLibName));.....}
ECOM also provides a standard mechanism to import specified implementations at runtime.
- [Question 2: Check the usage of trap]
Trap uses as little as possible. Trap consumes more resources than you think. Because the kernel execution mechanism calls ttrap: Trap () and ttrap: untrap (), and allocate a structure at runtime to store the current stack context so that the previous state can be returned in case of a leave event. If your class contains more than 6 traps, it means that the class design is incorrect and needs to be re-designed. If possible, move the trap to the outer layer of the function call.
- [Question 3: Check service usage and optimization]
It is not advisable to connect to the service immediately when the application starts (when connected to the instantaneous Service), because this will cause a chain reaction, and the dependent parts of multiple service programs will load into the memory. If the service is rarely used, this method can be regarded as invalid resource usage. It is always wise to connect to the instantaneous service on demand. It should be designed in this way. The implementation of the customer API is always separated from the actual service implementation. In this way, when the client program is linked to the customer api library, the service program dependencies will not be automatically loaded, but this should occur when the service program is actually started. When designing a service program, you always need to consider its usage and various resources required during the operation. Assume that the Service provides three functions, such as read, write, and notification. read/write operations are not frequent. In this case, it is best to divide it into two services. One provides heavyweight functions, such as reading/writing/replacement, which will be reprinted/uninstalled as needed by the client, and the other Provides Lightweight Notification Services.
- [Question 4: compressing executable programs]
Use the compresstarget statement in the application's MMP file to indicate that the target executable file should be compressed. In this way, the code and data segments of executable files are compressed using the Huffman + lz77 algorithm. This will make the stored executable files use fewer spaces in the file system. When being loaded, the executable file loader can decompress the file. All executable files should not be decompressed. Only those occupying a large amount of space can be decompressed.
- [Question 5: file scanning]
If the drive letter is known, the drive letter is always specified in the file path. If no drive letter is specified, all available drive disks will be searched by standard Symbian OS. If your file is in Z:, you will have a huge loss, because Z: is always the last to be searched.
- [Question 6: Check for memory usage optimization]
In s60 applications, the default thread stack size is only 8 KB, so only small objects should be created on the stack and removed from the stack as early as possible. Except for the basic type, we should always PASS Parameters by reference instead of by value. The creation of large objects and arrays should be completed in the heap, And the lifecycle of automatic variables should be minimized.
- [Question 7: Check the use of default parameters]
If we declare the default value for function parameters, additional code will be generated by the compiler, which may be a fee. If the default value is commonly used, it is worthwhile to reload this method, instead of providing the default parameter value.
void MyFunction( TInt aCounterVal, TInt aParamLength = 2);Can be written as :void MyFunction( TInt aCounterVa );void MyFunction( TInt aCounterVal, TInt aParamLength );
- [Question 8: Check the usage of references and pointers]
Avoid passing large objects by value, always reference or pointer first. Unless null values are acceptable, it is better to use references because it is more suitable for ease of use. A reference cannot be re-assigned. If you need to point to an object first and then to other objects, you can use a pointer. A reference is always better than a pointer because it is more effective. Based on the fact that the compiler must retain the NULL pointer value through all conversions, that is, the compiler must test the null value, to create more commands.
- [Question 9: Check the inline keyword and initialization list]
The Inline keyword does not force the compiler to do that. It relies entirely on the compiler to determine its own behavior. If the function is large (for example, more than 3-4 lines of code), avoid using inline. We recommend that you use the inline method in the following situations: Get or set methods, simple constructors of the t class, and thin templates. There are more problems with the inline method. For example, implementing code changes will cause binary incompatibility. If you have a limited memory resource problem, instead of a speed problem, the method call cost is higher than the large segment of Inline code. The use of constructors to initialize the list is more effective than assigning values in the constructor. Because the default constructor is used, the class member variables are automatically constructed, which takes precedence over those entries in the class constructor. However, the constructor list does not allow us to verify the variables, so it is not always appropriate.
- [Question 10: Checking disk space problems]
Before writing any code, we should always consider disk space issues. Especially when we write something on the MMC or memory card. Sysutil has API functions such as diskspacebelowcriticallevell () and mmcspacebelowcriticallevell (). These functions can be called when a programmer wants to write bytes. When calling the preceding methods, you do not need to pass fileserver session objects, which makes them less expensive. Otherwise, you need to create a temporary session. RFS also provides API functions to solve this problem.
- [Question 11: Check the use of descriptors]
Descriptors are designed to be efficient, but fully dependent on their use. If possible, try to use t-class pointer descriptors such as tptrc and tptr instead of tbuf or tbufc, because tbuf is built on the stack (rarely on the stack) and is only used for small strings, generally, a maximum of 16 characters are recommended. For hbufc, try to use rbuf as much as possible because it is the optimized and dynamic nature. Avoid creating multiple local instances of class objects, such as tfilename and tparse. It is better to use member variables. Avoid using the _ L macro because additional runtime cost related to the construction of the temporary descriptor object is also the reason they are voided in the product code.
- [Question 12: Check the use of arrays]
The use of arrays is completely dependent on requirements. If the array size is known during compilation, tfixedarray can be used. However, in most cases, dynamic data is required. We can use carrayxxxx or pointer-type arrays such as carrayptrflat, carrayptrseg, and rpointerarray. Generally, rarray or rpointerarray is preferred, instead of carray or carrayptr. Based on the runtime extension needs, we can consider using the segmented or flat type. Iteration on the flat data is fast because of the continuity, and the expansion of the segment array is very fast, because the internal implementation is the linked list.
[Translator: We recommend that you consider the above issues before writing a program, instead of tuning the code after writing it .]