If you've spent any time in the competitive programming world, you know and love #include <bits/stdc++.h>. Itโs the ultimate time-saver, a magic bullet that imports almost the entire standard library at once. No more worrying about whether you forgot to include <vector> or <algorithm>.
But what happens when you move from writing a quick competitive programming solution to building a massive, multi-file software project? That magic bullet suddenly turns into a massive bottleneck.
Let's dive into exactly why this happens, how the C++ compiler processes your code, and the modern C++20 solution that is changing the game.
The "Old Way": The 4-Step Compilation Process
To understand the problem, we have to look at how C++ compilation was designed back in the 1970s. It fundamentally follows a "copy-paste" philosophy across four steps:
Source Code (
.cpp): This is the code you write.Preprocessing (
.i): The preprocessor scans for#symbols. When it sees#include <vector>, it physically opens the vector file, copies all 10,000+ lines of code, and pastes them directly into your file.Compilation (
.obj/.o): The compiler translates that massive wall of text into assembly and machine code.Linking (
.exe/.out): The linker stitches your object files together, pointing your code to the actual logic stored in the standard library.
NOTE:- .exe for Windows and .out for Mac/Linux.
So what's the problem with <bits/stdc++.h>?
When you #include <bits/stdc++.h>, you are bringing in hundreds of header files. The preprocessor copy-pastes all of them into your .cpp file.
If you have 50 files in your project, and they all include this header, the compiler has to read, parse, and process those same tens of thousands of lines 50 times over. Even a seemingly simple #include <iostream> actually pulls in sub-headers like <ios>, <streambuf>, and <ios_base>, cascading into thousands of lines of code.
But wait, does this make my final program slower?
No! The C++ compiler is brilliantly lazy. It wonโt actually build the code for a vector until it sees you write vector<int> v;. If you include a header but never use its logic, the compiler simply ignores it for the final binary.
Execution Time: Not affected.
Binary Size: Not affected.
Compilation Time: Massively affected.
The Modern Way: C++20/23 Modules
The modern way completely replaces the #include directive with Modules. Instead of including individual files, you simply write import std;, which replaces all headers like<iostream>, <vector>, <map>, etc.
You still get your .obj files and your final .exe/.out file, but it effectively eliminates Step 2 (Preprocessing) and makes Step 3 (Compilation) infinitely faster. But how?
import std; // Replaces all headers <iostream>, <vector>, <map> etc.
int main() {
std::vector<int> prices = {4500, 1200, 8900, 2300};
std::ranges::sort(prices);
std::cout << "Cheapest price: " << prices[0] << "\n";
return 0;
}
The core shift is that Modules change the process from "Reading Text" to "Loading Binary Data"
Here is exactly what happens under the hood when we compare the old Header system to the new Module system:
1. Precompilation & The BMI (Binary Module Interface)
When you first use import std;, the compiler processes the library just one time. It converts the code into a Binary Module Interface (BMI).
This BMI contains the "compiled knowledge of the library" in a format that the compiler understands instantly.
2. The Parsing Battle
With Headers: The compiler has to do Lexical Analysis (converting characters to words) and then Parsing (understanding the logic). This is a heavy mathematical process for the CPU. As you noted, doing this heavy process 100 times for 100 different files is exhausting.
With Modules: The BMI is already parsed. The compiler doesn't have to read through the text again; it simply points to the BMI.
3. Disk I/O vs. Memory Mapping(mmap)
With Headers (Disk I/O): To compile 100 files with '#include ', the OS has to physically open the vector file 100 times and pull that text from the SSD or Hard Drive into the CPU.
With Modules (Memory Mapping): Modern compilers use Memory Mapping (
mmap). The first timefile1.cppimports std, the OS loads the binary module straight into the computer's RAM. For the next 99 files, the compiler just looks at that exact same spot in the RAM. It never goes back to the slow disk.
The Verdict
If you are doing competitive programming where the file is small and you need to code fast, #include <bits/stdc++.h> is perfectly fine because it doesn't affect your execution time, and compilation time gets affected by only 2-5 sec which causes no problem.
But if you are working on a large-scale project? Stop using it. Stick to specific, selective headers to save your compiler from walking through thousands of unnecessary lines of code, or better yet, make the jump to C++20 Modules!

Top comments (0)