Precompiled Headers in C++

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hey look guys my name is Jenna welcome back to my C++ series so today we're gonna be talking all about precompiled headers in C++ we're gonna first of all start off by just talking about them what they are and why you should be using them and then after that we're gonna jump into both Visual Studio and GCC give us boss and kind of take a look at a real world example of how to actually set them up and see the actual benefits in a very simple example okay so first of all what are pre-compiled headers I'm sure that if you've been like using simple software any kind of moderate amount of time you've probably heard of them but I would place a fair bet that a lot of you probably aren't using them because really they're not really required to be used there's something that is probably quite vital for larger projects but for most of you who are kind of still learning you're probably not you probably don't have massive projects in which you would really need to use C++ and if you haven't actually worked somewhere or worked on a large project than you probably would never have really set this up by yourself unless someone's explicitly kind of told you hey you know you should start using pre-compiled headers so there's a good kind of bet that I think a lot of you guys aren't using them but you need to use them they will kind of help you out so much.what precompiled headers actually do is they give you an opportunity to grab a bunch of header files and convert them into essentially a kind of compiled format that the compiler can then use instead of having to read those header files over and over again so here's an example right I use the standard template library quite a lot right on my be using vector might be using string we might be using other things in the standard library like you know STD see out all of those kind of files right especially the Senate template library comes from header files right they're made out of header files because they're templates they have to be defined in header files now every time that I include vector let's just use that as an example every time I include vector in one of my C++ files it needs to read that entire vector header file and compile it not only that with vector includes a bunch of other include files right that needs to happen as well the preprocessor has to go in copy all of that into that vector file essentially you end up with something that's probably around a hundred thousand lines of code or so that needs to be parsed tokenized and compiled in some form before you actually get into your main kind of file that you're trying to compile because if your main file includes vector then vector has to be copied and pasted into that main file and then that whole kind of conglomerate of code that whole massive code has to be parsed and compiled every time if you suddenly decide I'm going to change my main kind of file that I'm trying to compile a little bit and my main file I just mean a C++ file right it's just the one that what I'm working on right now because if you have us if you have many stable Clause files in your project many places that include a vector obviously they're going to be individually included in every single file right because that's how the compiler works every translation unit is compiled separately and then later the link kind of links all that together if you're unfamiliar with that definitely check out the video on how an astable sauce works and how the compiler works and how link works all that fun stuff anyway the point is every time you make a change in that people to save us loss file the whole thing has to be written filed right so that vector class all that's part of that vector file has to be copied and pasted into your staples last file paused all over again from scratch and compiled again because you've got a nerve added a blank line or something like that right what that means is that your compile times are going to be a lot longer than they potentially could be not only that but think about the fact of you have multiple fields they both loss files in your project they all include vector right well suddenly you have to keep pausing that same code all over again every single time for each translation unit for each CPP file that you're actually trying to compile that takes time so what you can do instead is use something called a precompiled header what that does is it takes a bunch of header files which you tell it to take in write a bunch of code essentially and it compiles it once and it stores it in a binary format that is way faster for the compiler to actually deal with that in just texts because already in a past kind of state it's in binary not text right that's ready to go and every time you include that pregnant Pal pedophile it already has everything you need that's it right so instead of it pausing that entire back to file every single time it only needs to look at the precompiled header which is already in a great fast easy to use binary format is it used for the compiled letters binary format right which it just takes every time you need vector because you've included your break and pulse header in your source file that you're currently compiling and all the dot is there and what that means is that it results in way way way faster compilation times okay your projects will be compiled like many times faster because of this especially as you're kind of as you're kind of project size I guess grows and you end up having more and more stable fluff files more and more header files all of that stuff and you can keep shopping in more stuff into the break above header and also you have more source files which make compiling that use common headers it's just gonna be exponentially faster it's gonna be so much better so you need to need to need to use precompiled headers if you care about compilation times if you say that your compilation times are getting out of hand and it's taking like a minute to compile you can potentially reduce that to like eight seconds if you just kind of start using precompiled headers okay so I've talked about the greatness of breaking fault headers and we're gonna go ahead and take a look at an example in a minute but I also want to talk about what not to do with break compiled headers so what I've mentioned so far kind of as to what a precompiled header actually is it is essentially a header file which includes a bunch of other header files right so because of that a lot of people might be like okay well I can just put everything in my project into that PCH into that precompiled header and if I do that then we'll all get really fast build times right well yes but but if you put stuff in your break apart header which changes so stuff in your actual project that you're likely to change because you're working on your project obviously the precompiled header has to be rebuilt and that takes time right that could potentially end up slowing down your compilation so do not put frequently changing files into that preg hello really what it should be useful there's nothing wrong with you putting kind of your own project files into there like if I have something like a log H file which doesn't really change because how often do I touch my own logging library right I kind of read written that once it's not like I have to keep adding stuff to it that's fine you can put that into your breaker bulkhead up because that's something that first of all is needed a lot right which also makes it convenient to use because since you're including your precompiled header in every single source file now right you also have access to those logging functions so that's really kind of easy to use now now it's kind of it makes it more convenient because you don't need to manually include log in every single safety big file that you have in your project cuz you're including the precompiled header which includes log so that's good because it adds convenience right but also I've made sure that I'm not doing it if I'm going to be changing if I'm currently working on my logging library probably shouldn't be in the compiled cattle and then in the protocol header right because every time I change that that loved our H header file it needs to get recompiled into the written vault header which means the whole route to help bring compiled header I might have said Reichenbach header the whole precompiled header has to be rebuilt from scratch every single time so don't put stuff like that in it what it's really used for is probably like external I would say sternal dependencies or there's a bit of an issue with dependencies which as we'll talk about in a minute but essentially it's used for it's vitally used for code that isn't yours so for example the SCL write code that is in the standard template library or in the standard kind of C++ library or like the windows API like if you want include Windows dot H that is a massive header file which includes a billion other header files right you are not going to be modifying windows at H you're not going to be modifying the standard template library right so there is no reason for it to kind of not be in a precompiled header file right it should be there because that is a lot of code probably many times more code than your actual application right and when you think about it what's your application made out of say for fluff libraries standard template library windows API calls that kind of stuff right that's what it's made out of he uses that stuff all the time and and that's part of that you'll never be touching so put all of that into your pre-compiled header right that stuff belongs there because that is a lot of code probably many times more code than your actual application than your actual project right you're compiling that every single time per CPP file that's terrible put it into a program bolt head up where it can just be left alone and you'll get the benefit of first of all getting access to everything in every city of a file right you won't need to actually include like memory for example if you want to use smart pointers or include a vector all the time because it's gonna be in the PCH which will be included in there in every single say plus plus file that you actually ride so you'll have access to that it's convenient and it will speed everything up really quickly now I decide something about dependencies one thing that the PCH can actually do is because you shove everything into your PCH it can potentially hide what's actually being used now it's theoretically speaking me if I write asleep but if I write a CPP file that uses like I don't know a window library or something right and I put that window in library into the into my PCH it's not really apparently clear if you read that CPP file you don't actually know what it needs it might need J love W my windowing library it might not need it might need like some other dependencies but because all of your dependencies are in the PCH if you just isolate that CPP file and you take it you don't actually know what it needs and it can be very difficult until meant in terms of mod like modularity and code reuse for you to actually be like okay well now I can take this file put into another project wait I have no idea what it needs right if you just had include jail FW or something in that actual header file and in your actual or CPP file that you've taken you'll be very clear wouldn't it the this file needs this file right but if you have just include PCH and then a bunch of includes in that PCH it can kind of make it a little bit harder so that's what a lot of people kind of mention when you when they're dealing with people that is that you know be careful maybe don't include all dependencies there because it'll make it clearer and easy to read if you actually include your dependencies per kind of file that needs them and I agree with that to an extent depends how kind of specific that dependency is if you're making a game engine and you want to include yourself w you know in your PC age I mean you can but on the other hand think about how many actual source files need that not that many right probably like if you've written a game engine quite unquote properly probably only one CPP file actually needs to include gels W right because everything else will kind of be abstracted and in your own API so in that case well you know why put gel W to your break apart header you can so if I make anything worse right probably however it does probably have readability a bit and also you'll it'll be extra stuff for your pre-compile tether to compile that really only one CPP file means stuff that you should put in there as I mentioned is like STL right because strings or vectors or standard sea out might be something that you that you broadly want in a lot of places right and stuff that you don't want to keep breaking poly from scratch every time gelid lb on the other hand you know kind of something you've probably compiled once and you're done so that's kind of the idea of breaking belt headers I've talked a lot about this whole thing let's jump into it and take a look at a few examples and we'll also kind of measure how long it takes to build using pre-compiled headers and not eating precompiled headers so what we've kind of got here is a very simple hello world application it says hello world right however it includes this file which i've named pc HH now freaking bath header is kind of what I've called it can be called absolutely anything Visual Studio by default makes something called STD AF X dot H if you kind of use the C++ wizard to actually create a project or you kind of create a project from a template I usually create empty projects which doesn't have any of that but um this file can be called anything you want it to be called and right now even though it's called PC H bridge don't be fooled we're not using precompiled headers in this project what I'm doing is I'm simply including in my in my PC H I've just got a header file which includes a bunch of other header files and includes some basic kind of save applause library stuff it includes some other structures as well as the windows API some windows on H right this is a lot of code right I probably don't need to tell you that it's a lot of code if I just for fun go ahead and say give me the preprocessor output so if I go to preprocessor and then pre press s to a file if I shut that on and then I just hit control f7 to build this file and I take a look at what is actually in this main dot I file if we scroll down to the very bottom you can see that I mean here's our kind of see up hello world it's like three hundred and seventy thousand lines of code that's a lot of stuff right that is what will be recompiled every single time you include this in your actual CPP files right in every single CPP file individually it has to go over and process three hundred and seventy thousand lines of source code and then tokenize them and then compile them and then do all of that stuff right every single time we want to avoid that so what we can do is actually use frigging part headers so I can turn this into a break and path header this is a good this is a pretty good example of what you might have in your PC age right I haven't got any kind of I mean this is just a this is just a hello world program so of course I don't have my own kind of massive set of code but really I'm just including stuff that I know I'll never touch and stuff that is likely going to be needed by this kind of program so what I'm going to do is first of all once you have your header file make a CPP file which includes your header file this is visual studios way of doing things we're gonna take a look at what J plus plus actually needs and a clang is a very similar similar to GCC as well but what we need to do for Visual Studio is actually create a CPP file which includes our header file right and then on that CPP file we need to right-click hit properties and then go on disable saves under safes under say a bus bus we need to go to precompiled headers and then select outbreak and palette header to be create right so for this specific PCH dot CPP file we're going to create a precompiled header and then hit OK then I'm going to go to the entire properties for the entire project right the property for the entire project and I'm going to and I'm going to on the safe sickles Wells precompiled headers select this to be used so our entire project now uses precompiled headers and then the brigham Bob header file that we will use will be of course PC H dot H ok hit OK now this of course will apply it to everything so if I now look at the properties for main dot CPP as an example you can see it's set to use a program called headers and then it includes and then a specifies which one is used and then this is what it will actually compile to right this is the output file this is the compiled binary format of our actual pre-compiled header and then because we've set that for the project it applies to everything so in summary set the project who used your precompiled headers and specify which one is used and then for your CPP file which includes PC H or H set it to create precompiled header and that's all you need to do ok so now if I just right click build you can see we should build successfully and everything should be fine that's how we create PC ages now let's take a look at how how much that actually sped up at compile time now keep in mind this is a very basic project which should be even more kind of impactful because you can see that we really don't have anything here we've only got one CPP file even but if we right click go to properties and then just disable this for now so not using precompiled headers will kind of get an easy kind of comparison to the before state so what I'll do is under tools options and the projects and solutions vegetables as project settings I'm gonna set build timing to yes just so that it times how long our build takes and then I'm just gonna clean this and then build it and we'll take a look at how long that takes ok so that actually failed because conop and main dodo BJ for some reason I'm just gonna go to properties and make sure because I did the preprocessor to pre-process to a file I'll just make sure that's set to no and then I'm going to clean this project and then I'm going to build the project ok so you can see building the project a clean build took three point three seconds right and then if I edit the source file for example if print HelloWorld twice and I build that again you can see that a subsequent build takes about one and a half seconds right let's just do that again just for fun to make sure that we get a more reliable timing there we go one and a half seconds right okay cool so now let's just switch this let's just switch this precompiled headers thing to use and then I'm going to again clean it we're gonna see how long a clean build it takes okay about two seconds so that's I mean it was three point three seconds before so that's considerably faster and now let's edit this source file and just duplicate that line look at that half a second okay sit down from one-and-a-half seconds to have a second that's three times faster I'm gonna remove this and try it again just to make sure and there you go you can see just how much faster using precompiled headers actually made this compilation and this project is absolutely tiny cool so let's take a look at how we might do this in G+ Boston will also kind of time that so the first thing I'll do is understand the source directory here which has these three files all I'm going to do first of all is just see how long it takes to compile this project without using frequent alt headers so if I just go ahead and write time T plus Boston and we're using C++ 11 for this and then just mean does he be I'll try and compile that see how long it takes there we go 1.5 seconds I'll go and like modify the source file again by just adding another line and then we'll see how long this takes okay about one-and-a-half seconds right cool so now let's go ahead and actually create a precompiled header so i do that by basically just compiling that pc a shot h file that's all you need to do in GCC so i'll hit enter you can see it takes a little bit of time and then what it generates is this PC H or H dot g CH net festival look at how big it is 114 megabytes that's quite large second of all der let's go ahead and order late a WC just so it's basically a clean build and then we'll go ahead and run this again look at that point two eight seconds right if I go ahead and remove this again and do another compilation let's I just do a clean thing here 0.2 seconds right about 0.3 seconds let's just round up you can see that is down from 1.5 seconds 2.3 seconds so much fuss that's like five times faster okay so hopefully all these examples have kind of shed some light on to why you should be using precompiled headers they speed up your build times a lot and they also make it more convenient to actually write code since you don't have to keep including commonly used header files over and over again I hope that made sense let me know in the comments below if you've been using precompiled headers that this is the first time you've heard of it if you think that this is something that you should use or kind of your experience with them in general I every software project should be using precompiled headers there's no real kind of should I use them should I not every predator should be using them what to put into your breaking ball Petter has a different story and we've covered a few of the kind of good examples of what you should put in there but whether or not you should be using them yes absolutely unless you're making a little sandbox project and you don't want to go through the hassle of setting it up not that it's particularly hard then yeah I probably would avoid that but otherwise you should be using for compile tez hope you guys enjoy this video if you did you can hit the like button you can help support this series and everything that I do here on this channel by going to pee I'm not home for the churner you get videos early as well as access to cool kind of source software development repositories and many other cool rewards and it does help me make more of these videos I hope you guys enjoyed this leave some comments below as to what you want to see next in the staples loss series I'll probably be kind of since I'm focusing a lot on the game engine series I'll be kind of making videos to do with that probably standalone Sables loss videos based on topics that we cover there but also that game engine series is a really good example to see all of these kind of concepts that we've been learning in this again the staples boss series actually come together so definitely check that out I will see you guys next time goodbye [Music]
Info
Channel: undefined
Views: 66,200
Rating: 4.9659333 out of 5
Keywords: thecherno, thechernoproject, cherno, c++, programming, gamedev, game development, learn c++, c++ tutorial, game engine, how to make a game engine, game engine series, Precompiled Headers in C++, pch, precompiled header
Id: eSI4wctZUto
Channel Id: undefined
Length: 21min 30sec (1290 seconds)
Published: Thu Nov 29 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.