Home > Back-end >  How to analyze and improve the compilation speed (C/C) program?
How to analyze and improve the compilation speed (C/C) program?

Time:09-15

A people vs 2010 program, compiled, load data and operation, the need for an hour, and when to change the code and then run again to see the results for an hour to compile. So wouldn't it be a waste of time, how to do? So how to modify the program, how to improve the efficiency?
When we encounter this situation, is at a loss? How to prevent encountered such a situation, we some methods to analyze the process accelerated,

The hardware, the compiler
Use better computer is undoubtedly the best choice for an operation on, the second, also can compile options to optimize for the compiler, for example in VS environment, can be done by configuration properties, specific steps are as follows, you can refer to: https://blog.csdn.net/yizhou2010/article/details/52635288

Coding style
Use the add more, the decrement instructions and compound assignment expression
What do you think of using i++, I=I + 1, I +=1 is there a difference? Let's test the C code:

Void asd () {}
Int main () {
int i=0;
i++;
Asd ();//easy to distinguish the context
I=I + 1;
Asd ();
I +=1;
return 0;
}
The disassembly:

Mov [RBP + I], 0//I initialize the
The add [RBP +] I, 1//i++;
Call _Z3asdv; Asd (void)
The add [RBP + I],//I=I + 1;
Call _Z3asdv; Asd (void)
The add [RBP + I],//I + 1=1;
We see the result is the same, but in the more complex expression that will generate a few more instructions, and use the I +=1, is always better than write I=I + 1 is a little more then look good,

Division with multiplication or shift to express
Division is the process by multiplication inverse push, in turn lose (if x is minus) y ^ (2 ^ 31), y ^ 2 ^ (30),... 8, y ^ ^ 4 y, y ^ 2, y ^ 1, lose the corresponding number of y on the results combined with the corresponding amount, generally speaking, the more time-consuming, use a demo to test the

Auto time_start=STD: : chrono: : system_clock: : now ();
Int iCount=100000;
Double k;
for (int i=0; i <1000000; I++)
{
TMP=iCount/2;
}
STD: : chrono: : duration Time_spend=STD: : chrono: : system_clock: : now () - time_start;
Double test1=time_spend. The count () * 1000;
Cout<& lt;" Test1 cost "& lt; & lt; Time_cost & lt; & lt;" "Ms & lt; & lt; Endl;

Time_start=STD: : chrono: : system_clock: : now ();
for (int i=0; i <1000000; I++)
{
TMP=iCount * 0.5 f;
}
Time_spend=STD: : chrono: : system_clock: : now () - time_start;
Test2=time_spend. The count () * 1000;
Cout<& lt;" Test2 cost "& lt; & lt; Time_cost & lt; & lt;" "Ms & lt; & lt; Endl;

Time_start=STD: : chrono: : system_clock: : now ();
for (int i=0; i <1000000; I++)
{
TMP=iCount & gt;> 1;
}
Time_spend=STD: : chrono: : system_clock: : now () - time_start;
Test3=time_spend. The count () * 1000;
Cout<& lt;" Test3 cost "& lt; & lt; Time_cost & lt; & lt;" "Ms & lt; & lt; Endl;
Output result will be, we found that the displacement of multiplication and division than three to five times to save time, shift relative to character is the most save time,

Multi-purpose initialized directly, using less copy initialization
String s1="hiya";//copy the initialization
String s2 (" hello ");//initialize
String s3 (10, 'c');//initialize
When we use copy initialization, we ask that the compiler will copy the right operand to the object is created, if necessary for type conversion, will certainly waste of the resources, time, and direct the compiler initialization is required to use ordinary function matching to choose and we provide the parameters of the matching of constructors and copy constructor,

Let's take a look at how to say in the Primer

When used in object of class type, copy form of initialization and direct form different: direct initialization direct calls with arguments constructor, duplicate initialization is always calls the copy constructor, duplicate initialization using the specified first constructor creates a temporary object, and then use copy constructor copies the temporary object to is creating object
"There is a said:

Initialization often directly and copy to initialize only the differences on the lower level optimization, however, for does not support the type of replication, or the use of explicit constructor, there are essential differences between:
Ifstream file1 (" filename ") ://ok: direct initialization
Ifstream file2="filename";//error: the copy constructor is private
Static local variables, local variables, global variables and static global variable
Is present in the stack for local variables, the space just a modification of the distribution of the esp the contents of a register;
Static local variables are defined within the function, the static local variables defined in the front with the static keyword to identify, static local variables in functions in multiple calls, only the first time experience variable definitions and initialization;
When a file or data use repeatedly, should be stored in global variables, avoid reloading use;
A static global variable is static storage way, a static global variable limits its scope, namely effective only within the definition of the variable source files, in the same source program of other source files can't use it,
Static variables are inefficient, when a piece of data is read and write repeatedly, its data will stay in the CPU level Cache (Cache)

Code redundancy
Avoid large loop, loop to avoid statement
In the process of programming, the most influence on the speed of code to run tend to be circular statement, I remember when writing the matlab, deal with large data, are banned in circulation, especially multilayer nested loop statement,

Secondly, as far as possible to a nested loop control within the three layers, research data show that when the loop nested more than 3 layers, the programmer's understanding of circulation ability will be greatly reduced, at the same time, the execution efficiency is low, therefore, if the code loop nested more than 3 layers, recommends the design cycle or the code rewritten into a child function within the loop,

for (i=0; i<100; I++)
{
For (j=0; j<5; J++)
{
For (j=0; j<5; J++)
{
/* processing code */
}
}
}
Multiple for loop, if possible, should as far as possible will be the longest cycle on the lining, the shortest cycle on the outermost layer, in order to reduce the CPU cut across the number of cycle layer

for (i=0; i<100; I++)
{
For (j=0; j<5; J++)
{
/* processing code */
}
}
To:

For (j=0; j<5; J++)
{
for (i=0; i<100; I++)
{
/* processing code */
}
}
Logic judgment not to use in the loop, when the number of a for loop is large, implement redundant judgments will not only consume the system resources, but also will interrupt the cycle "assembly line" homework, make the compiler can't optimize the circulation processing, reduce the program execution efficiency

If (condition)
{
for (i=0; i {
/* processing code */
}
}
The else
{
for (i=0; i {
/* processing code */
}
}
Avoid recursion and recursive calls itself is constantly, so it is consume resources, or even cause stack overflow and the program crashes, and so on the question!

Int Func (int n)
{
If (n & lt; 2)
return 1;
The else
Return Func n * (n - 1);
}
Therefore, mastering the cycle optimization all kinds of practical technology is to improve the efficiency of the program, is also a high level program must possess basic skills,

Try not to use inheritance and multiple inheritance
Multiple inheritance increased the complexity of the class inheritance hierarchy, debugging difficulty increase the risk of course also increased, and the use of a parent class pointer to a subclass object into a complex thing, use the c + + dynamic_cast to perform force provided by the transformation, but dynamic_cast is at run time rather than during compilation, conversion, thus will bring some slight performance loss, that suggests to use c + + type conversion to the built-in type conversion functions, not forcibly converting

Use less template, because templates are compile-time technology, the use of templates will increase compilation time
There's a phrase in c + + primer3:

Between multiple files to compile the same function template definition adds unnecessary compilation time short, for a zhidaovector function, such as size (), if appear in different CPP, the compiler in these files are the vector: : size () compile again, and then remove the duplicate function when links, obviously increased the compilation time, template function requires instantiation zhidao at compile time, so don't put the realization of the template code in the header file (instantiated in a header file), then every CPP to use the template of the template instantiation again again, so the increase in staff translated time
Encoding dependencies
Statement and realize the separation, remove unnecessary # include
When using an include, only need to include that the interface file
Not all of the files will need to include the header iostream, defines the output function reference is good
Ostream header file, also don't replace with iosfwd, why, as long as the parameters and return type to declare before (forward declared) can compile
To minimize the parameter passing, multi-purpose references to pass parameters,
Bool func1 (string s1, string s2)
Bool func2 (string * s1, s2) string *
nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
  • Related