Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
Simple question, what's the difference between them?
EDIT:
actually I have a question about how to detect immediately when user press any keyboard button, as example I have a variable named temp[1] = 0, then when user pressed "1" then at the monitor appears 0 right after user press the key (without pressing "enter" first), I'm creating a simple hangman game actually..
Of course, iostream has extra overhead, but that is usually insignificant to the program. Usually people will choose the C++ cin/cout because it is considered fitting to the "C++ style". You'll hear that come up a lot with languages in general (especially python--to do things a "pythonic" way). Usually there is some overarching style behind a particular language, depending on the language's goals, so it is considered better to follow that style. So I would personally use cin/cout unless you have a good reason not to.
Printf is a very heavy function. It should only be used for generating natural language strings. It should never be used in performance code due to the format parsing overhead.
For performance code use some form of stream directly.
actually I have a question about how to detect immediately when user press any keyboard button, as example I have a variable named temp[1] = 0, then when user pressed "1" then at the monitor appears 0 right after user press the key (without pressing "enter" first), I'm creating a simple hangman game actually..
Use an input library. In Linux this is probably done by opening an input stream from the input driver file. In Windows you use their input library from DirectX. Some Window management libraries have input as part of them.
You should use standard functions like getchar.
getch is not only non-standard, but it also has different behavior (gets input from the keyboard rather than stdin).
Printf is a very heavy function. It should only be used for generating natural language strings. It should never be used in performance code due to the format parsing overhead.
For performance code use some form of stream directly.
Use an input library. In Linux this is probably done by opening an input stream from the input driver file. In Windows you use their input library from DirectX. Some Window management libraries have input as part of them.
Yes the numbers vary between runs roughly by 10%, but still as you see, printf is a loot quicker than C++ ostream object cout.
This is because while printf has some formatting to do, it is still only 1 function call, and the equivalent cout is actually 5 function calls. Dont forget that ostream inherits from basic_ios and that inherits from ios_base. + the guts of << operator has to check whether the stream state is goodbit(otherwise the operation cannot proceed), it must construct sentry and do checks with that, then it has to get the buf object(streambuf type) and it all calls virtual methods, which must be dispatched, further increasing overhead.
The code was run on default Release mode on Visual studio 2012.
On the other hand, printf has no compile-time checks for types passed, so even printf("%d", std::vector<std::string>(5)[0]); is valid, but will result in garbage printed.
This is because while printf has some formatting to do, it is still only 1 function call, and the equivalent cout is actually 5 function calls. Dont forget that ostream inherits from basic_ios and that inherits from ios_base. + the guts of << operator has to check whether the stream state is goodbit(otherwise the operation cannot proceed), it must construct sentry and do checks with that, then it has to get the buf object(streambuf type) and it all calls virtual methods, which must be dispatched, further increasing overhead.
Well what do you expect if you do the silly thing of calling OS system calls 5 times instead of once?
Either buffer the output so it calls the os I/O less, or merge the string together before printing it. The idea is that you have the same number of I/O calls except that one of them uses a generated string using string logic where as the other uses a formatted string. As soon as any sort of I/O kernel level swap is involved any bench mark difference in performance goes out the window. The only thing you have proved is that I/O is very slow and that compared with printf, removing a single I/O call will be much more of an optimization.
for(int i = 0; i < LOOPTIMES; ++i)
{
std::string s = "Number " + std::to_string(i) + ": " + std::to_string(randInfo[i]) + "\n";
std::cout << s;
}
and it is still the same, 1 second vs 14.9
edit: Even if I directly access the stream object as so:
C++:
for(int i = 0; i < LOOPTIMES; ++i)
{
std::string s = "Number " + std::to_string(i) + ": " + std::to_string(randInfo[i]) + "\n";
std::cout.rdbuf()->sputn(&s[0], s.size());
}
its still the same speed.
There is no denying that C++ streams are slow, even the members of C++ committee knows about this, but they said that they didnt find more efficient way yet to do it. If you feel you know of something faster, propose it to C++ standard committee
Default C++ strings are probably not allocation optimized for multiple concatenations. Using a suitable sized character array and manually managing the string might be faster as it avoids the dynamic allocation overhead of c++ strings. Formated printing may use such a buffer internally so only be subject to a memory copy as opposed to multiple full blown memory allocations. Memory allocations can result in OS system calls which would also explain the huge slowness.
A lot of people under estimate the overhead of short lived objects being created and destroyed from the memory allocation point of view. Without extending their life time, simply having an object cache or pool can greatly improve performance at the cost of a larger process address space and potentially less page cohesion.
Memory allocation is only very slow when new pages of virtual memory are required. These can only be requested from the OS (as it has to modify page mappings) so generate a kernel level call. Equally well it is slow when freeing all elements on a page as then the virtual memory page has to be de-allocated which also requires a kernel level call. Obviously sub-page allocation and freeing (done within an already existing page that is not completely clear) is done entirely within process address space so is performed a lot faster. Something silly like your strings constantly allocating and de-allocating a page from the process with each loop would result in very poor performance for even the most trivial of tasks.
I personally dont think it is much of a problem, if you are printing > 600 lines/second into console, you are doing something wrong
But just to prove that printf is order of maginute faster than cout, here is the best test that you can get:
C++:
#include <iostream>
#include <cstdio>
#include <string>
class Benchmark{
long long startT;
bool paused;
long long lastPRet;
public:
Benchmark() : startT(__rdtsc()), paused(false), lastPRet(0) {}
long long pause()
{
if (paused)
return lastPRet;
paused = true;
return lastPRet = __rdtsc() - startT;
}
long long get()
{
return __rdtsc() - startT;
}
void start()
{
paused = false;
startT = __rdtsc();
}
};
#include <random>
#include <chrono>
int main()
{
const int LOOPTIMES = 10000;
const float CPU_CLOCK_APPROX = 3600000000.f;
std::vector<int> randInfo;
auto currentTime = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::mt19937 generator(currentTime);
//generate random info:
for(int i = 0; i < LOOPTIMES; ++i)
{
randInfo.push_back(generator());
}
Benchmark m;
long long pTotal = 0;
for(int i = 0; i < LOOPTIMES; ++i)
{
m.start();
printf("Number %d: %d\n", i, randInfo[i]);
pTotal += m.get();
}
auto pPrintf = pTotal / CPU_CLOCK_APPROX;
long long cTotal = 0;
for(int i = 0; i < LOOPTIMES; ++i)
{
std::string s = "Number " + std::to_string(i) + ": " + std::to_string(randInfo[i]) + "\n";
m.start();
std::cout.rdbuf()->sputn(&s[0], s.size());
cTotal += m.get();
}
auto pCout = cTotal / CPU_CLOCK_APPROX;
std::cout << "\n\n\nLooping " << LOOPTIMES << " times:\n";
std::cout << "\tprinf(): " << pPrintf << " sec\n";
std::cout << "\tcout << ...: " << pCout << " sec\n";
std::cin.get();
}
only the output is benchmarked. Both outputs are benchmarked in the same way, so you can rule out the time it takes to add integer to integer.
This still outputs printf(): 1 sec; cout << ...: 14 secs.
I wonder how many more arguments you will try to pop before finally saying you were wrong and C++ streams(that even the creators of them say that they are slow) are far slower than C's printf.
If you STILL dont believe me, take the code and compile it, you will see that the printf output goes into console order of magnitude faster than cout output
Let's argue more about the speed of a debugging method that will take 0.000001% of your program's execution. It seems a reoccurring theme on this forum.
even FILE* beats fstreams, not by such margin tho(a few percent better performance with unformatted input/output, if you do formatted one, that is different)
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.