Writing efficient and concise C language code is the goal pursued by many software engineers. This article describes some experiences and experiences in programming.
First move: Change Time with Space
The biggest contradiction in computer programs is the contradiction between space and time. From this perspective, we should reverse thinking to consider the program efficiency, we now have 1st moves to solve the problem-change the space for time. For example, the value assignment of a string:
Method A: the general method
#define LEN 32char string1 [LEN];memset (string1,0,LEN);strcpy (string1,"This is a example!!");
|
Method B:
const char string2[LEN] ="This is a example!";char * cp;cp = string2 ;
|
You can use pointers to perform operations.
From the above example, we can see that the efficiency of A and B is incomparable. In the same bucket, B can directly use the pointer, and A needs to call two character functions to complete the operation. B's disadvantage is that flexibility is not as good as. When you need to change the content of A string frequently, A has better flexibility. If you use method B, you need to pre-store many strings, although it occupies A large amount of memory, however, the program execution efficiency is achieved.
If the system has high real-time requirements and memory requirements, I recommend that you use this method. This variable is a macro function instead of a function. Example:
Method C:
#define bwMCDR2_ADDRESS 4#define bsMCDR2_ADDRESS 17int BIT_MASK(int __bf) { return ((1U << (bw ## __bf)) - 1)<< (bs ## __bf);}void SET_BITS(int __dst, int __bf, int __val){ __dst = ((__dst) & ~(BIT_MASK(__bf))) | (((__val) << (bs ## __bf)) & (BIT_MASK(__bf))))}SET_BITS(MCDR2, MCDR2_ADDRESS,ReGISterNumber);
|
Method d:
#define bwMCDR2_ADDRESS 4#define bsMCDR2_ADDRESS 17#define bmMCDR2_ADDRESS BIT_MASK(MCDR2_ADDRESS)#define BIT_MASK(__bf) (((1U << (bw ## __bf)) - 1)<< (bs ## __bf))#define SET_BITS(__dst, __bf, __val)((__dst) = ((__dst) & ~(BIT_MASK(__bf)))| (((__val) << (bs ## __bf))& (BIT_MASK(__bf))))SET_BITS(MCDR2, MCDR2_ADDRESS,RegisterNumber);
|
The difference between a function and a macro function is that a macro function occupies a large amount of space while a function occupies time. You need to know that function calling uses the system stack to store data. If the compiler has the stack check option, generally, some Assembly statements are embedded in the function header to check the current stack. At the same time, the CPU also needs to save and restore the current site during function calling to perform stack pressure and elastic stack operations, therefore, it takes some CPU time to call a function.
This problem does not exist in macro functions. Macro functions are only embedded into the current program as pre-written code and do not generate function calls. Therefore, they only occupy space. This phenomenon is particularly prominent when the same macro function is frequently called.
The D method is the best position operation function I have seen. It is part of ARM's source code and implements many functions in just three lines, covering almost all bit operation functions. The C method is its variant, and the taste needs to be carefully understood.
Second TRICK: solve problems using mathematical methods
Now we assume the second trick of writing efficient C language-using mathematical methods to solve the problem. Mathematics is the mother of computers. Without the foundation and foundation of mathematics, there will be no computer development. Therefore, when programming, using some mathematical methods will increase the execution efficiency of the program by an order of magnitude. For example, 1 ~ Sum of 100.
Method E:
int I , j;for (I = 1 ;I<=100; I ++){ j += I;}
|
Method F
int I;I = (100 * (1+100)) / 2
|
This example is a mathematical case that I was most impressed with. It was tested by my computer teacher. At that time, I only had a third-grade primary school. Unfortunately, I didn't know how to use the formula N × (N + 1)/2 to solve this problem. Method E loops 100 times to solve the problem. That is to say, at least 100 assignments, 100 judgments, and 200 additions (I and j) are used ); method F only uses one addition, one multiplication, and one division. The effect is self-evident. So now, when I compile a program, I use my brains to find patterns and maximize the power of mathematics to improve the program running efficiency.
Third move: Bit operations
The third way to achieve efficient C language writing-bit operations. Reduce division and modulo operations. The bit of data in a computer program is the smallest unit of data that can be operated. In theory, you can use the bit operation to complete all the operations and operations. Generally, bit operations are used to control hardware or perform data transformation. However, flexible bit operations can effectively improve the efficiency of program running. Example:
Method G
int I,J;I = 257 /8;J = 456 % 32;
|
Method H
int I,J;I = 257 >>3;J = 456 - (456 >> 4 << 4);
|
Literally, H is much more troublesome than G. However, you can check the generated assembly code carefully to understand that the method gcall uses the basic modulo function and division function, which can be called by both functions, there are also a lot of assembly code and registers involved in the operation, while method H is just a few related assembly, the code is more concise, more efficient. Of course, due to the differences in compilers, there may be little difference in efficiency. However, from the perspective of ms c and arm c I have encountered, the efficiency gap is not small. The relevant Assembly Code is not listed here.
When using this method, you must note that the CPU usage is different. For example, a program written on a PC that passes debugging on a PC may cause code risks when it is transplanted to a 16-bit platform. Therefore, this approach can be used only on the basis of certain advanced technologies.
Step 4: Assembly embedding
The fourth measure is embedded assembly. "In the eyes of people familiar with assembly languages, C language programs are all spam ". Although this argument is somewhat radical, it makes sense. Assembly language is the most efficient computer language, but it cannot be used to write an operating system? Therefore, to achieve program efficiency, we had to adopt a flexible method-Embedded Assembly, mixed programming. For example, assign array 1 to array 2, and each byte must be consistent.
Char string1 [1, 1024], string2 [1024];
Method I