_Na2Th's blog

By _Na2Th, history, 7 years ago, In English

This is a tip for C++ programmers who use the bits header to include every library from C++.

#include <bits/stdc++.h>

Even more so with C++11, it may take some time for it to compile on your machine. I speak by experience: it took me more than 4s to compile every single time. This would drive me crazy during contests.

I know it works on linux with gcc. I would guess it works on any unix with gcc, but I really don't know.

The solution I offer here is to precompile the headers, and avoid processing every header file every time.

I'll explain by example, showing how I would prepare for the upcoming contest, round 429.

The first thing to do is to make the folder I'll leave my code in, and copy the template file I have into it.

mkdir cf429
cp temp.cpp cf429/

The template goes something like

#include "bits/stdc++.h"
#define mt make_tuple
using namespace std;

int main(){
}

Note the use of #include "bits/stdc++.h" instead of #include <bits/stdc++.h>. This is important, since it makes the compiler first look for the local copy, and only afterwards try to look in the libraries. This is what ensures that the code will run on the Online Judge and take advantage of the precompiled local version in my machine.

Then I would need to find where the header is. It is possible to do so by compiling a program which includes the library with the -H flag. I'll just compile my template.

g++ -H temp.cpp

The first file is the header we are looking for. In my machine it was on /usr/include/c++/7.1.1/x86_64-pc-linux-gnu/bits.

So I can just copy this file into the directory I am going to use during the competition and precompile it. I do it in a way that I do not have to change the header, so that I can submit the file normally.

To be able to do so, create a bits directory, copy the file into it, and compile the header with the same flags you use. In the code below, remember to change the directory to the one you found with the g++ -H command.

mkdir bits
cp /usr/include/c++/7.1.1/x86_64-pc-linux-gnu/bits/stdc++.h bits/
cd bits
g++ -std=c++11 stdc++.h

Now, just to ensure that I'll will have the same flags, I use a Makefile.

cd ..
echo "CXXFLAGS = --std=c++11" > Makefile

and done! I can just wait for the contest to begin, and compile my programs much faster with a simple make A.

Note that you can freely modify the local header copy, removing some stuff that you deem useless, to make it compile even faster. Also, you can then just copy this local version into the directories used in the competition. With this special local version, it is quite easy even to make a script that does the set up mentioned above.

  • Vote: I like it
  • +52
  • Vote: I do not like it

| Write comment?
»
7 years ago, # |
  Vote: I like it 0 Vote: I do not like it

Auto comment: topic has been updated by _Na2Th (previous revision, new revision, compare).

»
7 years ago, # |
Rev. 2   Vote: I like it +27 Vote: I do not like it

That really makes a difference. It should work with gcc (regardless the OS). In my case it reduced the compilation time by a factor of 6.

You could also precompile the actual header

g++ -std=c++11 /usr/include/long_path_to_your_libraries/bits/stdc++.h

and it would work for every directory on your system. Personally I think this is more convenient, although less customizable.

  • »
    »
    7 years ago, # ^ |
      Vote: I like it +10 Vote: I do not like it

    Yeah, on my machine it got 6 times faster too, but by cherrypicking the headers in the local version I got the compilation time down to ~.3s, which is 12 times faster.

    Aside from not being advisable to change the global header, you would need sudo access to compile, which is not the case in competitions.

    Some modification of this procedure can be used as a preparation on a ACM-ICPC style competition, even if you have no sudo privileges.

    • »
      »
      »
      7 years ago, # ^ |
      Rev. 2   Vote: I like it +10 Vote: I do not like it

      You are not changing the global header, just precompiling it to spare reprocessing it all the time (which involves a lot of conditional expansions). GCC is smart enough to use the precompiled header only when possible (same set of flags, same version, etc). If you really want to change the header, then it's better to create a copy but just to precompile it is already a nice optimization.

      About the permission issue, in my case it didn't require any special permissions. The only issue I can think of is that you can't create a file inside the long_path/bits directory (which you need because GCC creates a .gch file). I always get confused with directory permissions, so I can't say what permissions you actually need.

  • »
    »
    4 years ago, # ^ |
      Vote: I like it +2 Vote: I do not like it

    Don't know if anyone else is facing this issue, but I dont see any difference with precompiling headers in windows. Is there anything I am doing wrong.

    • »
      »
      »
      4 years ago, # ^ |
        Vote: I like it +1 Vote: I do not like it

      Add -H in your g++ compilation command. If everything is set up correctly, you should get something like this as your output. Otherwise, you will get a very long list of header files and maybe some other text. Untitled.png Larger version of the image.

      The exclamation mark means that gcc is able to detect and use the precompiled header.

      • »
        »
        »
        »
        4 years ago, # ^ |
        Rev. 3   Vote: I like it 0 Vote: I do not like it
        g++ -H -std=c++17 stdc++.h
        

        I used this command, it showed a whole list of different headers, but not that ! at the end.

        So, was the pre-compilation of headers successful?

        • »
          »
          »
          »
          »
          4 years ago, # ^ |
            Vote: I like it 0 Vote: I do not like it

          If "stdc++.h.gch" file is created in your folder, then it means the pre-compilation is successful.

          • »
            »
            »
            »
            »
            »
            4 years ago, # ^ |
            Rev. 2   Vote: I like it 0 Vote: I do not like it

            Still, the compilation takes 8.5 to 9.5 seconds :'(. I am using sublime text 3, on windows 10.

            • »
              »
              »
              »
              »
              »
              »
              4 years ago, # ^ |
                Vote: I like it +1 Vote: I do not like it

              you have to compile your code with same flag.
              g++ -H -std=c++17 code.cpp

              • »
                »
                »
                »
                »
                »
                »
                »
                4 years ago, # ^ |
                Rev. 2   Vote: I like it 0 Vote: I do not like it

                Thank You!!

                It reduced compilation time to 3.5 seconds.

              • »
                »
                »
                »
                »
                »
                »
                »
                4 years ago, # ^ |
                  Vote: I like it 0 Vote: I do not like it

                Actually, now I found a solution to my problem. If I use c++14 tag instead of c++17, the processing is really fast, and the program finishes in less than 2 seconds.

                I wonder why it happened.

                • »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  4 years ago, # ^ |
                    Vote: I like it 0 Vote: I do not like it

                  yes. change windows power plan to battery recommaded if not.

            • »
              »
              »
              »
              »
              »
              »
              4 years ago, # ^ |
                Vote: I like it +1 Vote: I do not like it

              The first compilation will always take the usual time. Then after that the subsequent compilations will take around 0.7-1 second depending on the code. I am using sublime text as well. And please compile the code with the same flags you used during pre-compilation.

              • »
                »
                »
                »
                »
                »
                »
                »
                4 years ago, # ^ |
                  Vote: I like it 0 Vote: I do not like it

                First compilation, which is done like...

                g++ -H -std=c++17 code.cpp ?

                And then compilations, just by pressing ctrl+B ?

        • »
          »
          »
          »
          »
          4 years ago, # ^ |
            Vote: I like it +2 Vote: I do not like it

          To precompile the header:
          g++ -std=c++17 -other-flags-here stdc++.h

          To use the precompiled header:
          g++ -std=c++17 -other-flags-here -o file_name.exe file_name.cpp

          To check if gcc actually used the precompiled header:
          g++ -H -std=c++17 -other-flags-here -o file_name.exe file_name.cpp

          Make sure to compile your code with the same flags used to precompile the header.

      • »
        »
        »
        »
        3 years ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        Bro I am windows user but I am not able to precompile i did all the steps its still takes same time

»
6 years ago, # |
  Vote: I like it 0 Vote: I do not like it

I wrote a small script to do the same.

»
4 years ago, # |
  Vote: I like it 0 Vote: I do not like it

"and done! I can just wait for the contest to begin, and compile my programs much faster with a simple make A." Can anybody explain this step??

  • »
    »
    4 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    When you are on the folder in which you set up everything, you can type

    make A

    in your terminal and press enter, and it will compile your program A.cpp

    • »
      »
      »
      4 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      'make' is not recognized as an internal or external command, operable program or batch file.

      how to deal with above error?

  • »
    »
    4 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    what he means is using a MAKE file.

    A makefile is a file containing a set of directives used by a make build automation tool to generate a target/goal

    Basically you can write a makefile to compile your codes and then simply call it by make. check here

    i.e this is a part of my makefile for contests

    Main:
    	prob
    	
    a:
    	g++ probA.cpp -o prob
    	prob
    b:
    	g++ probB.cpp -o prob
    	prob
    

    Now if you want to run the compiled code you can type

    make

    Or if you want to compile and run a file you can

    make a

    • »
      »
      »
      3 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      That link no longer is leading to the installation page

»
4 years ago, # |
  Vote: I like it -21 Vote: I do not like it

IMO just type out the proper headers. It only takes a few seconds. I don't understand why people would use a lazy hack to include the entire standard library, realize that it increases compilation time, and then use another hack to reduce the compilation time just to not have to type 5 lines of #includes.

»
4 years ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

You can just go to bash folder and make custom command for that. After typing "_bash nameofyourcommand_" it will do it faster.

Edit: works only for linux. idk unix

»
4 years ago, # |
  Vote: I like it 0 Vote: I do not like it

I think you can directly precompile the stdc++.h in the original folder so you don't have to copy it for different folders.