I'm using Windows7 using CPython for python3.22 and MinGW's g++.exe for C++ (which means I use the libstdc++ as the runtime library). I wrote two simple programs to compare their speed.
Python:
x=0
while x!=1000000:
x+=1
print(x)
C++:
#include <iostream>
int main()
{
int x = 0;
while ( x != 1000000 )
{
x++;
std::cout << x << std::endl;
}
return 0;
}
Both not optimized.
I ran c++ first, then i ran python through the interactive command line, which is much slower than directly starting a .py file.
However, python outran c++ and turned out to be more than twice as fast. Python took 53 seconds, c++ took 1 minute and 54 seconds.
Is it because python has some special optimization done to the interpreter or is it because C++ has to refer to and std which slows it down and makes it take up ram?
Or is it some other reason?
Edit: I tried again, with \n
instead of std::endl
, and compiling with the -O3
flag, this time it took 1 min to reach 500,000.
Though Python is an interpreted language, it first gets compiled into byte code. This byte code is then interpreted and executed by the Python Virtual Machine(PVM). This compilation and execution are what make Python slower than other low-level languages such as C/C++.
Python is an excellent tool enabling just that. It allows for focusing on the idea itself and not be bothered with boilerplate code and other tedious things. However, Python comes with a major drawback: It is much slower than compiled languages like C or C++.
Q: Why is C faster than Python? Answer: The fact that Python is an interpreted language and every action in the code needs to be interpreted by the main CPU to perform what is required makes Python slower than C. Python is run on what is called a Virtual Machine.
One of my colleague at work told me that Python code is faster than C++ code and then showed this topic as an example to prove his point. It is now obvious from other answers that what is wrong with the C++ code posted in the question. I still would like to summarize my benchmarks which I did in order to show him how fast a good C++ code can be!
There are two problems with the original C++ code:
It uses std::endl
to print a newline in each iteration. That is a very bad idea because std::endl
does more stuff than simply printing a newline — it also forces the stream to flush the buffer accumulated so far; flushing is an expensive operation as it has to deal with hardware – the output device. So the first fix is this: if you want to print a newline, just use '\n'
.
The second problem is less obvious as it is not seen in the code. It is in the design of C++ streams. By default, C++ streams are synchronized to the C streams after each input and output operation so that your application could mix std::cout
and std::printf
, and std::cin
and std::scanf
without any problem. This feature (yes, it is a feature) is not needed in this case so we can disable this, as it has a little runtime overhead (that is not a problem; it doesn't make C++ bad; it is simply a price for the feature). So the second fix is this: std::cout::sync_with_stdio(false);
And here is the final optimized code:
#include <iostream>
int main()
{
std::ios_base::sync_with_stdio(false);
int x = 0;
while ( x != 1000000 )
{
++x;
std::cout << x << '\n';
}
}
And compile this with -O3
flags and run (and measure) as:
$ g++ benchmark.cpp -O3 #compilation
$ time ./a.out #run
//..
real 0m32.175s
user 0m0.088s
sys 0m0.396s
And run and measure python code (posted in the question):
$ time ./benchmark.py
//...
real 0m35.714s
user 0m3.048s
sys 0m4.456s
The user
and sys
time tell us which one is fast, and by what order.
Hope that helps you to remove your doubts. :-)
There isn't anything obvious here. Since Python's written in C, it must use something like printf
to implement print
. C++ I/O Streams, like cout
, are usually implemented in a way that's much slower than printf
. If you want to put C++ on a better footing, you can try changing to:
#include <cstdio>
int main()
{
int x=0;
while(x!=1000000)
{
++x;
std::printf("%d\n", x);
}
return 0;
}
I did change to using ++x
instead of x++
. Years ago people thought that this was a worthwhile "optimization." I will have a heart attack if that change makes any difference in your program's performance (OTOH, I am positive that using std::printf
will make a huge difference in runtime performance). Instead, I made the change simply because you aren't paying attention to what the value of x
was before you incremented it, so I think it's useful to say that in code.
I think we need more information, but I would expect you're building an un-optimized build of C++. Try building it with the -O3
flag. (someone who knows GCC better will have more and better recommendations). However, here's some timings from a completely untrustworthy source: http://ideone.com. I ran each 5 times to get some measure of variance on the timing, but only the origonal C++ varied, and not much at that.
Python: http://ideone.com/WBWB9 time: 0.07-0.07s
Your C++: http://ideone.com/tzwQJ time: 0.05-0.06s
Modified C++: http://ideone.com/pXJo3 time: 0.00s-0.00s
As for why my C++ was faster than yours, std::endl
forces C++ to flush the buffer immediately. '\n'
does the newline without the forced buffer flush, which is much much much faster.
(note: I only ran to 12773, since ideone.com kills processes after they display a certain amount of output, that was the most the server would give me)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With