13

How do I find out where the compiler spends its time?

My build is too slow, I'm already using a RAMdisk for the VC++ temporary files and it doesn't make any difference. (I have an SSD, so I expected no difference.)

Most single C++ files in this project take approx. 2 seconds to compile which seems awful (as I also don't have any in-project parallelization because I'm using VS2005).

How can I optimize this? Don't optimize without profiling, but how do I profile the compiler?

Note: These were not really helpful:


Let's add a good comment: Do you have lot's of templates? How large are your files on average? Do you checked on including only the minimum of necessary headers

No, I did not. I could (and pro'lly will) of course. I may be able to find something, but it's all speculation and trial and error!

"Everybody" tells you that you should only optimize after measuring/profiling, but when optimizing compilation times, we're back to trial&error?


Note: The proposed "hack" from the comments with __TIME__ does not work, at least not on Visual-C++, because (as the docs state): The most recent compilation time of the current source file. The time is a string literal of the form hh:mm:ss. -- I guess one could at least get timings for single compilations units with this stamp, but it doesn't help to drill down into an compilation unit.

Community
  • 1
  • 1
Martin Ba
  • 37,187
  • 33
  • 183
  • 337
  • Do you have lot's of templates? How large are your files on average? Do you checked on including only the minimum of necessary headers? – stefan Mar 14 '13 at 10:02
  • are you using precompiled headers? – Zdeslav Vojkovic Mar 14 '13 at 10:10
  • @MartinBa With "including only the necessary minimum of headers" it's not try and error, it's good practice. Concerning the average size of files: Compilers need to parse the whole thing, so obviously there is a perfomance limit given by the size of the file. I'd suggest an incremental build system in which only changed files are recompiled. Then you really don't have to worry about long compile times. – stefan Mar 14 '13 at 10:17
  • 1
    you could try to put something like `#pragma message( "Starting " __TIME__ )` and `#pragma message( "Completed " __TIME__ )` around places you suspect are taking a while to compile - e.g. where you have lots of heavy template instantiations –  Mar 14 '13 at 10:30
  • Just a note: even VS2005 supports intra-project parallel compilation. Add `/MP` to your command line. There's no clickable property for it, but you can add it to "Additional command-line options." – Angew is no longer proud of SO Mar 14 '13 at 10:44
  • @Angew - I thought this is undocumented and "not supported" for VC++ (not only "not in the GUI") I think I don't want to ship binaries with such a switch. – Martin Ba Mar 14 '13 at 10:50
  • 1
    It doesn't get you a direct answer to 'where is the compiler spending its time?', but looking at the preprocessor output might give you a better idea of 'how much work is the compiler trying to do?': http://stackoverflow.com/questions/277258/c-c-source-file-after-preprocessing – Weeble Mar 14 '13 at 10:56
  • @MartinBa We do ship them (that is, did before switching to newer VS), but that's up to you, of course. – Angew is no longer proud of SO Mar 14 '13 at 11:04
  • @user1773602 - `__TIME__`does NOT work, at least not on Visual-C++, because (as [the docs](http://msdn.microsoft.com/en-us/library/b0084kay%28v=vs.80%29.aspx) state): *The **most recent compilation time** of the current source file. The time is a string literal of the form hh:mm:ss.* – Martin Ba Mar 18 '13 at 10:16
  • Ah, there is another question essentially asking the same thing: http://stackoverflow.com/questions/15873388/spotting-compilation-time-bottlenecks-in-order-to-compilation-firewall-efficient (And that one hasn't even got any answer, but a few useful comments.) – Martin Ba Aug 01 '13 at 08:44

3 Answers3

3

SysInternals ProcMon will show you all the I/O done by selected processes, including the timestamp when it happened and the full path.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • Hmmm ... seems tricky to get this done with VC++ ... I have `devenv.exe`, but this'll spawn `cl.exe` (via some intermediary I think). Have you ever tried this on a VS build? – Martin Ba Mar 14 '13 at 10:52
  • Process Monitor has very flexible filters. You can set a filter that matches the process executable. You don't need to use the PID of the running process. – Weeble Mar 14 '13 at 10:54
2

There are a few ways to optimize your compile time:

  • Use a precompiled header. If you use Visual C++ than use the "stdafx.h". By default "stdafx.h" is set to be the precompiled header but I would recommend you checking this to make sure it is.

  • Use Linux :). If you don't have to use Windows for what you are doing I recommend using Linux. The compilation times on it are a lot better. Some of the reasons are: ext4 is ~40% faster than NTFS on average and it has a better process scheduler. When it comes to processor operations, Linux usually does it ~x1.8 - x2 times faster and compiling is processor dependent.

  • Use another Compiler. Clang/LLVM is known to have better compilation speeds and also has support for precompiled headers.

Lilian A. Moraru
  • 1,046
  • 1
  • 12
  • 20
  • *If you use Visual C++ than use the "stdafx.h", put all your headers in it.* - what a bad advice. **all** headers is certainly *not* what one would want to put in `stdafx.h` (and, yes, I'm using it for selected common headers) – Martin Ba Mar 14 '13 at 10:53
  • MS certainly does not recommend this. *All* headers? provide a reference please. – Martin Ba Mar 14 '13 at 10:56
  • 1
    Well, even if you put all headers in there it wouldn't be much of a problem. The whole reason for a PCH is to *pre*-compile, so you pay that cost only once anyway. But indeed, it should only contain large, often-used and rarely-changing headers. – Joey Mar 14 '13 at 13:22
  • @Joey +1 - That's what I meant. – Lilian A. Moraru Mar 14 '13 at 15:27
1

TL;DR : Use MS vcperf to analyse your Build.

Note: This question is from 2013 and the tooling from 2019, so, yep, there was some wait here. :-)

MS has released vcperf which builds on their C++ Build Insights which is basically a toolchain allowing you to profile the compilation process.

https://devblogs.microsoft.com/cppblog/introducing-c-build-insights/

C++ Build Insights makes use of vcperf, a tool that allows you to capture a trace of your build and to view it in the Windows Performance Analyzer (WPA).

Martin Ba
  • 37,187
  • 33
  • 183
  • 337