Is there a performance impact of using multiple cout statements?

I’m interested in whether there is a performance difference in the different ways of using cout? For example in the lecture:

cout << "Welcome to Bulls and Cows!" << endl; cout << "Can you get the " << WORD_LENGHT; cout << " letter I'm thinking of?" << endl;

Here we use multiple cout expressions. Would it be more effective performance wise to write:

cout << "Welcome to Bulls and Cows!" << endl << "Can you get the " << WORD_LENGHT << " letter I'm thinking of?" << endl;

Does it not impact performance to call cout multiple times rather than just feeding it with subsequent values? I’m not worried for this specific example, but rather when used in a larger project.

1 Like

Good question, this is a bit of an educated guess but it might be a good starting point for a discussion.

If I recall correctly cout effectively represents the output buffer. << is an overloaded operator that is responsible for inserting characters into the buffer so it is the number of times that you call <<, especially for different types (string, int, etc.) that determine what has to be loaded into memory and processed by the CPU at run time. I’m thinking that the compiler should be more efficient at loading the static strings as they can be preset don’t need to be manipulated so much at run time but it has been about 20 years since I last thought about optimization at this level so I may have completely made that up. I think the endl will cause the buffer to flush to the output device where /n doesn’t but that may have changed in the current C++ version.

My experience is that it is flushing to the buffer and writing to the output device that is the slow part. That could be console, a good old xTerm (that can definitely get behind), a file or in the really old days a printer. If you are writing an application where writing to a console (or a file) is going to be the bottleneck then creating a custom multi line buffer may get you more performance than changing the number of times you use cout as in the example above.

I’m hoping that made at least some sense and if I’m completely wrong someone will let us all know, I won’t be offended!

You could test this by writing the 2 bits of code tossing it in a loop to run a few thousand times and then sending the output to /dev/null to remove the console overhead. Time them and let us know what you find :slight_smile:

1 Like

Thanks for the reply. I’m not worried it will become a bottleneck in development. I simply want to learn the “best” way to write code since I’m learning from scratch. While I don’t think this difference would make a significant impact on the overall performance, I suppose it would make a difference if I write various bits of code less effective than it could be. Maybe I’m worrying about completely unnecessary stuff? Like optimizing the carrying load of some ants while I have elephants contributing aswell?

Since I’m just starting out to code I struggle with how to code the test you recommend. I tried by googling, but I don’t know if it’s a good way of measuring. Basically checking clock() before and after each loop block.

#include <iostream>
#include <ctime>

using namespace std;

int main() {
	constexpr int WORD_LENGHT = 5;
	clock_t start1, end1, start2, end2;

	start1 = clock();

	for (int i = 0; i < 50000; i++)
	{
		cout << "Welcome to Bulls and Cows!\n";
		cout << "Can you get the " << WORD_LENGHT;
		cout << " letter I'm thinking of?\n";
	}

	end1 = clock();
	start2 = clock();

	for (int i = 0; i < 50000; i++)
	{
		cout << "Welcome to Bulls and Cows!\n"
		<< "Can you get the " << WORD_LENGHT
		<< " letter I'm thinking of?\n";
	}

	end2 = clock();

	cout << "\n\n\nThe interval was: ";
	cout << (double)(end1 - start1) / (double)CLOCKS_PER_SEC;
	cout << " seconds for multiple cout statements and ";
	cout << (double)(end2 - start2) / (double)CLOCKS_PER_SEC;
	cout << " seconds for a single cout statement." << endl;

	return 0;
}

I’m using Windows by the way, and I suppose the suggestion of sending the output to /dev/null is a GNU/Linux privilege? I suppose I have to settle with the content being printed 100,000 times.

According to the results of the 50,000 iterations of the two different code variations, using a single cout statement could be better performance wise (143.299 seconds vs. 137.343). However, I’m unsure of the legitimacy of the test, and it is according to this test only slightly faster. I suppose the results could be the reverse in a second test. I should probably focus on making the code look pretty and understandable. :slight_smile:

It should perform pretty much exactly the same because it results in near identical assembly.
https://godbolt.org/g/j4VRXF

Also benchmarked it using this code:

int main()
{
	using time_point = std::chrono::steady_clock::time_point;
	constexpr int WORD_LENGTH = 5;
	time_point t1 = std::chrono::high_resolution_clock::now();
	for (int i = 0; i < 50000; i++)
	{
		std::cout << "Welcome to Bulls and Cows!\n";
		std::cout << "Can you get the " << WORD_LENGTH;
		std::cout << " letter I'm thinking of?\n";
	}
	time_point t2 = std::chrono::high_resolution_clock::now();
	time_point t3 = std::chrono::high_resolution_clock::now();
	for (int i = 0; i < 50000; i++)
	{
		std::cout << "Welcome to Bulls and Cows!\n"
	  			  << "Can you get the " << WORD_LENGTH
				  << " letter I'm thinking of?\n";
	}
	time_point t4 = std::chrono::high_resolution_clock::now();
	std::cout << "multiple cout took " << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() << " ms\n";
	std::cout << "single cout took " << std::chrono::duration_cast<std::chrono::milliseconds>(t4 - t3).count() << " ms\n";
	return 0;
}

As well as using the Hayai benchmarking library and got these results

1 Like

Well, that explains it well. :slight_smile:

Thanks for the response as well as for the new benchmark code and the Hayai library. I will use your code in future benchmark attempts until I’m confident enough to try implementing the Hayai library. Interesting to see the similarities in the assembly code even though I’m not near competent enough to understand it.

My code for the Hayai benchmarks was just the following with commenting out one of the benchmarks and doing them seperately since I didn’t know how/if it’s even possible to have the outputs of the tests at the end of running them all rather than just the end of each test.

#include <iostream>
#include "hayai.hpp"
void MultipleCout()
{
	std::cout << "Welcome to Bulls and Cows!\n";
	std::cout << "Can you get the " << 5;
	std::cout << " letter I'm thinking of?\n";

}

void SingleCout()
{
	std::cout << "Welcome to Bulls and Cows!\n"
		<< "Can you get the " << 5
		<< " letter I'm thinking of?\n";
}

BENCHMARK(CoutTest, Single, 5, 10000)
{
	SingleCout();
}

//BENCHMARK(CoutTest, Multiple, 5, 10000)
//{
//	MultipleCout();
//}

int main()
{
	hayai::ConsoleOutputter consoleOutputter;

	hayai::Benchmarker::AddOutputter(consoleOutputter);
	hayai::Benchmarker::RunAllTests();

	return 0;
}
2 Likes

Thank you, that is really helpful. :smiley:

1 Like

Awesome, thanks Dan, very useful

Though you were correct in that the flushing is the slow part. Using std::endl instead of ‘\n’ when you don’t need to flush the buffer will have a (very minor) performance impact.
Though since most uses of std::cout and std::endl aren’t exactly in performance critical work and I would assume the majority would be for projects like this i.e., intro to C++, terminal based game, etc. in which you wouldn’t notice the difference I wouldn’t worry about it.

Relevant video:

Disregard the title of the video, it’s more like “Don’t use endl everywhere. Only when you want a newline and a flush”

2 Likes

what is different between const and constexpr?
can somebody explain?

a const variable means that the variable can’t be modified once initialised.
const at the end of a member function means that the function doesn’t modify class data.

constexpr means that the value can be deduced at compile time.

https://godbolt.org/g/YyvJDJ

As you can see in the link, in the non-constexpr function in the assembly you can see it has a function called square and calls it in main. However in the constexpr version it forgoes creating that and just uses the value 25 directly since it was deduced at compile time.

ok, but what’s profit from constexpr that I can deduced the value at compile time?

Increased runtime performance as the work was done at compile time rather than runtime.

Thank you DanM :slight_smile:

I learned a lot from just reading these posts. :grinning:

Privacy & Terms