Ways to reduce compilation time for C + + code

Source: Internet
Author: User

C + + code contains the header file and implementation of the two parts, the header file is generally provided to others (also called the customer) to use, but once the header file changes, no matter how small changes, all references to his files must be recompiled, compiling will take time, if you do the project is relatively large (such as two times package Chrome -like development), the time to recompile will waste most of your workday, and it's tiring, but your boss says you're not producing, and you're being Fired, is not very resentment ah, if you see this article earlier, you will be more efficient than your colleagues in the development of a few, so the fired will not be you, you say this article is not the value of the daughter! A joke :)

Anyway, how to introduce the compile time, I know 3 ways:

1. deletion of unnecessary #include, Alternative use of forward declaration (forward declared)

2. remove unnecessarily large piles of private member variables and use the "Impl" method instead

3. delete the inheritance between unnecessary classes

In order to clear these 3 points, or to give an example of better, this example I will step-by-step improvement (because I am also 1.1 points to explore out, if there is wrong, you can rest assured that the spray, I will and you in the end of the debate, hehe)

Now let's say you find a new job and take over a class written by a previous programmer, as follows

  Old.h: This is the class you receive     //      #include <iostream>     #include <ostream>     #include <list>      ///5 are file, DB, CX, deduce or error, level limited No template class     //Only with a virtual function with file and CX.     #include "file.h"  //class file     #include "db.h"  //Class db     #include "cx.h"  //class CX     #  Include "deduce.h"  //class deduce     #include "error.h"  //Class Error     class Old:public file, private DB {public     : Old          (const cx&);       DB  get_db (int, char*);       CX  get_cx (int, CX);       cx& fun1 (db);       Error  fun2 (error);       Virtual std::ostream& Print (std::ostream&) const;     Private:       std::list<cx> cx_list_;       Deduce       deduce_d_;     }; inline std::ostream& operator<< (std::ostream& os,const old& old_val )       {return old_val.print (OS);}

  

This class has been read, if you have seen the problem where, the next do not see, you are a master, these basic knowledge for you too small pediatric, if like the interview was asked to live leng a bit, please continue to see

First look at how to use the first: Delete unnecessary #include

This class refers to 5 headers , which means that the header files referenced by the 5 head files are also referenced, and in fact, there is no need to reference 5 , as long as a reference 2 One, it's all right.

1. Deletion of unnecessary #include, Alternative use of forward declaration (forward declared)

1.1 Delete header file  iostream ,  I just started learning C++&NBSP; c++ primer IOSTREAM&NBSP; OSTREAM&NBSP, enough.

1.2.ostream header file also do not, replace with iosfwd, Why, the reason is that the parameter and return type as long as the forward declaration can be compiled through, in the iosfwd file 678 Line (my environment is vs2013, the specific location of the different compilation environment may not be the same, but there is this statement) there is a sentence

typedef Basic_ostream<char, char_traits<char> > ostream;

Inline std::ostream& operator<< (std::ostream& os,const old& old_val)

{return old_val.print (OS);}

In addition, if you say this function to manipulate the ostream object, that still need to #include <ostream>, You only say half, indeed, this function to operate ostream object, but see his function implementation,

There is no definition of a similar std::ostream OS, Such a statement, say, any occurrence of such a definition statement, you must #include the corresponding header file, Because this is the request compiler allocates space, and if only forward to declare class XXX; How the compiler knows how much space to allocate to this object!

See here, the old.h header file can be updated as follows:

Old.h: This is the class you receive//#include <iosfwd>//New replacement header file #include <list>//5 are file, DB, CX,     Deduce or error, horizontal limited no template class//only with the file and CX have virtual functions.     #include "file.h"//class file, as a base class cannot be deleted, the compiler does not know how much space is allocated when instantiating an old object #include "db.h"//class db, as a base class cannot be deleted, as above #include "cx.h"//Class CX #include "deduce.h"//class deduce//error only used as parameter and return value type, replace # include "error with forward declaration       . h "class error; class Old:public file, private db {public:old (const cx&);       DB get_db (int, char*);       CX get_cx (int, CX);       cx& fun1 (DB);       Error fun2 (error);     Virtual std::ostream& Print (std::ostream&) const; Private:std::list<cx> Cx_list_; CX is a template type, neither a function parameter type nor a function return value type, so the cx.h header file cannot delete deduce deduce_d_; Deduce is a type definition and does not delete his header file};  Inline std::ostream& operator<< (std::ostream& os,const old& old_val) {return old_val.print (OS); }

  

So far, the deletion of some code, is not a good mood, it is said to see the level of a programmer is how high, not to see how much code he wrote, but to see how much he wrote less code.

If you have a deeper interest in C + + programming, you will still see the next text, and then remove the code further, but this time you're going to have to go a step further.

2. remove unnecessarily large piles of private member variables and use the "Impl" method instead

2.1. Write code using "Impl" implementation, reducing compiler dependencies for client code

The Impl method is simply to put the private member variables of the class into a impl class, and then leave the private member variable of the class only a impl* Pointer, the code is as follows

File Old.h     class Old {//publicly and protected member       /public and protected members private     ://Private member, as long as any one header file changes or the number of members increases, reduces , all clients referencing old.h must recompile       //private members; Whenever these change,       //All client code must is recompiled     };

  

Rewrite it like this:

File Old.h     class Old {//publicly and protected member       /public and protected members     private:       class oldimpl* Pimpl_;  Replace all of the original private member variables for this impl pointer, the pointer only need to forward the declaration can be compiled through, this writing will forward the Declaration and the definition of pointers together, it is entirely possible. //   Of course, you can also write separately         //A pointer to a forward-declared class     };     File Old.cpp     struct Oldimpl {//Real member variables are hidden here, random changes, the client's code does not need to recompile       //private members; fully hidden, can be
   //changed at'll without recompiling clients     };

  

I don't know if you can read it. Please write a kind of test, I just do, of course everything also has advantages and disadvantages, the following simple comparison:

implementing Classes with Impl

Do not use the Impl implementation class

Advantages

Type definition and client isolation, reduce The number of #include, increase the speed of compilation, library-side class arbitrary modification, the client does not need to recompile

Straightforward, straightforward, no need to consider heap allocation, release, memory leak issues

Disadvantages

For Impl pointers must use heap allocation, heap release, long time will produce memory fragmentation, eventually affect the program run speed, each call to a member function to go through the impl->xxx () of a forwarding

The client must recompile when any header file changes on the library side

Instead of Impl, This is true:

Only a virtual function is used with file and CX.     #include "file.h"       #include "db.h"       class CX; class error;     class Old:public file, private db {     public:
   
    old (const cx&);       DB  get_db (int, char*);       CX  get_cx (int, CX);       cx& fun1 (db);       Error  fun2 (error);       Virtual std::ostream& Print (std::ostream&) const;     Private:class oldimpl* Pimpl; Forward declarations and definitions here      }; Inline std::ostream& operator<< (std::ostream& os,const old& old_val)       {return old_val.print (OS ); }//implementation file Old.cppclass oldimpl{std::list<cx> cx_list_;deduce        dudece_d_;};
   

  

3. delete the inheritance between unnecessary classes

          Object-oriented provides inheritance of this mechanism, but inheritance does not misuse,   inherit FILE&NBSP; DB&NBSP; file DB&NBSP;

, inheriting FILE&NBSP; understandable,   because FILE&NBSP; OLD&NBSP; FILE&NBSP; CX&NBSP; There are virtual functions, private inheritance DB&NBSP; !&NBSP;

By private inheritance-a class cannot be derived from another class as a base class, similar to the functionality of the final keyword in Java , but from the instance it is obvious that this is not the intention, so this private inheritance is completely unnecessary, The functionality provided by the db class should be used in a way that is included so that you can

Delete the "db.h" header file, the DB instance can also be put into the impl class, the resulting class is this:

Only a virtual function is used with file and CX.     #include "file.h"       class CX; class error; class db;     Class Old:public file {public     : Old          (const cx&);       DB  get_db (int, char*);       CX   get_cx (int, CX);       cx& fun1 (db);       Error  fun2 (error);       Virtual std::ostream& Print (std::ostream&) const;     Private:       class oldimpl* Pimpl;//forward declaration and definition here      }; inline std::ostream& operator<< (std::ostream& Os,const old& Old_val)       {return old_val.print (OS);} Implementation file Old.cppclass oldimpl{std::list<cx> cx_list_;deduce        dudece_d_;};

  

Summary:

This article simply introduces several ways to reduce compilation time:

1. deletion of unnecessary #include, Alternative use of forward declaration (forward declared)

2. remove unnecessarily large piles of private member variables and use the "Impl" method instead

3. delete the inheritance between unnecessary classes

This is a few hope to help you, if I do not clear enough to refer to the attachment, where there is a complete example, you are welcome to comment, we discuss progress together, oh no, pay rise. Oh, in the next article I will Impl Implementation of the detailed analysis, look forward to it ...

Ways to reduce compilation time for C + + code

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.