Reduce the Compilation Time of C ++ code.

Source: Internet
Author: User

Reduce the Compilation Time of C ++ code.

C ++ code includesHeader fileAndImplementation FileHeader files are generally provided to other users (also called customers ).Header file changed, No matter how small changes, allReference his filesJustMust be re-compiledIt takes time to compile. If you do a large project (such as secondary encapsulation of chrome development), re-compilation will waste most of the work time, it took a very long time to do this, but your boss said that you did not produce it, and you were fired. Is it really hard? If you saw this article earlier, you will be more efficient than your colleagues in development, so that fired will not be you. Do you say this article is worth a thousand RMB! Joke :). Let's get down to the point. I know three ways to reduce the Compilation Time:

A. Remove unnecessary # include. The alternative method is to use forward Declaration (forward declared)

B. Delete unnecessary private member variables and use the "impl" method.

C. Delete inheritance between unnecessary classes

In order to clarify these three points, it is better to give an instance. I will improve this instance step by step (because I also found it out at 1.1 points. If something wrong, you can rest assured, I will argue with you to the end, haha), now let's assume that you find a new job and take over the classes written by a previous programmer, as shown below:

1 // old. h: This is the class you receive. 2 // 3 # include <iostream> 4 # include <ostream> 5 # include <list> 6 7 // 5 are file, db, cx, deduce or error, level Limited, no template class 8 // only use file and cx to have virtual functions. 9 # include "file. h "// class file10 # include" db. h "// class db11 # include" cx. h "// class cx12 # include" deduce. h "// class deduce13 # include" error. h "// class error14 15 class old: public file, private db {16 public: 17 old (const cx &); 18 db get_db (int, char *); 19 cx get_cx (int, cx); 20 cx & fun1 (db); 21 error fun2 (error); 22 virtual std: ostream & print (std: ostream &) const; 23 private: 24 std: list <cx> cx_list _; 25 deduce deduce_d _; 26}; 27 inline std: ostream & operator <(std :: ostream & OS, const old & old_val) 28 {return old_val.print (OS );}View Code

After reading this class, if you already see where the problem is, you don't need to read it next. You are a master. These basic knowledge is too child care for you, if you have been stunned during the interview, take a look.

1. First, let's see how to use Article 1: Delete unnecessary # include

This class references five header files, which means that the header files referenced by the five header files are also referenced. In fact, five header files are not required to be referenced, you only need to reference 2.

1.1 Delete unnecessary # include

Remove unnecessary # include. Alternative MethodForward Declaration(Forward declared ).

1.2 Delete header file iostream

Delete the header file iostream. When I first started learning c ++, I copied it according to "c ++ primer". As long as I saw the input, I added the header file iostream to the output file. A few years later, now I know this is not the case. Here we just define the output function, as long as we reference ostream.

1.3 Delete the ostream header file

The ostream header file should not be replaced with iosfwd. Why? The reason is that the parameter and return type can be compiled as long as they are declared in the forward direction. There are 678 lines in the iosfwd file (my environment is vs2013, the location of different compiling environments may be different, but this statement is provided:

1 typedef basic_ostream <char, char_traits <char> ostream; 2 3 inline std: ostream & operator <(std: ostream & OS, const old & old_val) 4 5 {return old_val.print (OS );}View Code

In addition, if you say that this function is required to operate the ostream object, you still need to # include <ostream>. You are only half right. Indeed, this function needs to operate the ostream object, however, please refer to his function implementation. There is no such statement defined in it as std: ostream OS, it is necessary to # include the corresponding header file, because this is to request the compiler to allocate space, and if only class XXX is declared in front, how does the compiler know how much space is allocated to this object! Here, the header file of old. h can be updated as follows:

1 // old. h: This is the class 2/3 # include <iosfwd> // new header file 4 # include <list> 5 6 // five are file, db, cx, deduce or error, level Limited, no template class 7 // only use file and cx to have virtual functions. 8 # include "file. h "// class file, which cannot be deleted as the base class. 9 10 // The Compiler does not know how much space is allocated when the old object is instantiated. 11 # include" db. h "// class db, which cannot be deleted as the base class, same as 12 # include" cx. h "// class cx13 # include" deduce. h "// class deduce14 // error is only used as the parameter and return value type and replaced with the declaration # include" error. h "15 class error; 16 17 class old: public file, private db {18 public: 19 old (const cx &); 20 db get_db (int, char *); 21 cx get_cx (int, cx); 22 cx & fun1 (db); 23 error fun2 (error); 24 virtual std: ostream & print (std: ostream &) const; 25 private: 26 std: list <cx> cx_list _; 27 // cx is a template type, neither function parameter type 28 29 // Nor function return value type, so cx. the h header file cannot be deleted 30 deduce deduce_d _; 31 // deduce is a type definition, and its header file is not deleted 32}; 33 inline std: ostream & operator <(std :: ostream & OS, const old & old_val) 34 {return old_val.print (OS );}View Code

So far, I have deleted some code. Is it a good mood? It is said that it depends on how high a programmer is, not how much code he has written, but how much less code he has written. If you are more interested in C ++ programming, you will continue to read the following text and delete the code, but this time you will find another way.

2. Delete unnecessary private member variables and use the "impl" method.. Use the "impl" Implementation Method to write code to reduce the compilation dependency of client code

The impl method is simply to put the classPrivate member variablePut all in oneImpl classAnd keep only one private member variable for this class.Impl * pointerThe Code is as follows:

1 // file old. h 2 class old {3 4 // public and protected members 5 6 // public and protected members 7 private: 8 9 // private member, as long as any header file changes or the number of members increases, 10 11 // decreases, all references old. the client of h must recompile 12 13 // private members; whenever these change, 14 15 // all client code must be recompiled16 };View Code

Rewrite it as follows:

1 // file old. h 2 class old {3 4 // public and protected members 5 6 // public and protected members 7 private: 8 class oldImpl * pimpl _; 9 10 // replace all the original private member variables with the impl pointer. the pointer can be compiled only by Forward Declaration, 11 12 // This method puts forward declarations and definitions of pointers together, and it is acceptable. 13 14 // Of course, you can also write 15 16 // a pointer to a forward-declared class17}; 18 19 // file old. cpp20 struct oldImpl {21 22 // The Real member variables are hidden here, and the client code does not need to be re-compiled 23 24/private members; fully hidden, can be25 26 // changed at will without recompiling clients27 };View Code

I don't know if you understand it. If you don't understand it, please write a class test. I did this. Of course, everything also has advantages and disadvantages. The following is a simple comparison:

  Use impl implementation class Do not use impl implementation class
Advantages The type definition is isolated from the client, reducing # include times, improving Compilation speed, modifying library classes at will, and the client does not need to re-compile Direct, simple, and clear. You do not need to consider heap allocation, release, and memory leakage issues.
Disadvantages For impl pointers, heap allocation and heap release are required. After a long time, memory fragments are generated, which affects the program running speed. Every time a member function is called, impl-> xxx () one-time forwarding Any header file on the library has changed and the client must be re-compiled.

After impl is implemented:

1 // only use file and cx to have virtual functions. 2 # include "file. h "3 # include" db. h "4 class cx; 5 class error; 6 7 class old: public file, private db {8 public: 9 old (const cx &); 10 db get_db (int, char *); 11 cx get_cx (int, cx); 12 cx & fun1 (db); 13 error fun2 (error); 14 virtual std: ostream & print (std :: ostream &) const; 15 private: 16 class oldimpl * pimpl; 17 // Forward Declaration and definition 18}; 19 inline std: ostream & operator <(std :: ostream & OS, const old & old_val) 20 {return old_val.print (OS);} 21 22 // implementation file old. cpp23 class oldimpl {24 std: list <cx> cx_list _; 25 deduce dudece_d _; 26 };View Code 3. Delete inheritance between unnecessary classes

Object-oriented provides the inheritance mechanism, but the inheritance should not be abused. the inheritance of old class is one of abuse. class old inherits the file and db classes, and the inheritance of file is the public inheritance, inheritance db is private inheritance, which can be understood by inheriting files. Because file contains virtual functions, old must be redefined. However, according to our assumptions, only file and cx have virtual functions, how to explain the private inheritance db ?! The only possible reason is:

Using private inheritance-a class cannot be used as a base class to derive other classes. Similar to the final keyword function in Java, this is obviously not the purpose of the instance, therefore, this private inheritance is completely unnecessary. Instead, you should use the functions provided by the db class in the include mode, so that you can put "db. h "header file deletion, the db instance can also be put into the impl class, and the final class is as follows:

1 // only use file and cx to have virtual functions. 2 # include "file. h "3 class cx; 4 class error; 5 class db; 6 class old: public file {7 public: 8 old (const cx &); 9 db get_db (int, char *); 10 cx get_cx (int, cx); 11 cx & fun1 (db); 12 error fun2 (error); 13 virtual std: ostream & print (std :: ostream &) const; 14 private: 15 class oldimpl * pimpl; 16 // Forward Declaration and Definition 17}; 18 inline std: ostream & operator <(std :: ostream & OS, const old & old_val) 19 {return old_val.print (OS);} 20 21 // implementation file old. cpp22 class oldimpl {23 std: list <cx> cx_list _; 24 deduce dudece_d _; 25 };View Code Summary

This article briefly introduces several methods to reduce Compilation Time:

1. Delete unnecessary # include. The alternative method is to use forward Declaration (forward declared)

2. Delete unnecessary private member variables and use the "impl" method.

3. Delete inheritance between unnecessary classes

 

Link: http://blog.jobbole.com/85275/

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.