I have made a program to compute the permutations of an 8 character string "sharjeel".
#include <iostream>
#include <time.h>
char string[] = "sharjeel";
int len = 8;
int count = 0;
void swap(char& a, char& b){
char t = a;
a = b;
b = t;
}
void permute(int pos) {
if(pos==len-1){
std::cout << ++count << "\t" << string << std::endl;
return;
}
else {
for (int i = pos; i < len;i++)
{
swap(string[i], string[pos]);
permute(pos + 1);
swap(string[i], string[pos]);
}
}
}
int main(){
clock_t start = clock();
permute(0);
std::cout << "Permutations: " << count << std::endl;
std::cout << "Time taken: " << (double)(clock() - start) / (double)CLOCKS_PER_SEC << std::endl;
return 1;
}
If I print each permutation along it takes about 9.8 seconds for the execution to complete.
40314 lshaerej
40315 lshareej
40316 lshareje
40317 lshareej
40318 lshareje
40319 lsharjee
40320 lsharjee
Permutations: 40320
Time taken: 9.815
Now if I replace the line:
std::cout << ++count << "\t" << string << std::endl;
with this:
++count;
and then recompile, the output is:
Permutations: 40320
Time taken: 0.001
Running again:
Permutations: 40320
Time taken: 0.002
Compiled using g++ with -O3
Why is std::cout so relatively time consuming? Is there a way to print that is faster?
EDIT: Made a C# version of the program
/*
* Permutations
* in c#
* much faster than the c++ version
*/
using System;
using System.Diagnostics;
namespace Permutation_C
{
class MainClass
{
private static uint len;
private static char[] input;
private static int count = 0;
public static void Main (string[] args)
{
Console.Write ("Enter a string to permute: ");
input = Console.ReadLine ().ToCharArray();
len = Convert.ToUInt32(input.Length);
Stopwatch clock = Stopwatch.StartNew();
permute (0u);
Console.WriteLine("Time Taken: {0} seconds", clock.ElapsedMilliseconds/1000.0);
}
static void permute(uint pos)
{
if (pos == len - 1u) {
Console.WriteLine ("{0}.\t{1}",++count, new string(input));
return;
} else {
for (uint i = pos; i < len; i++) {
swap (Convert.ToInt32(i),Convert.ToInt32(pos));
permute (pos + 1);
swap (Convert.ToInt32(i),Convert.ToInt32(pos));
}
}
}
static void swap(int a, int b) {
char t = input[a];
input[a] = input[b];
input[b] = t;
}
}
}
Output:
40313. lshaerje
40314. lshaerej
40315. lshareej
40316. lshareje
40317. lshareej
40318. lshareje
40319. lsharjee
40320. lsharjee
Time Taken: 4.628 seconds
Press any key to continue . . .
From here, Console.WriteLine() seems almost twice as fast when compared with the results from std::cout. What seems to be slowing std::cout down?
@rashedcs printf is definitely faster than cout because of internal syncing / flushing in iostream i/o which normally slows down their performance. However using iostream with sync_with_stdio(false) makes i/o operations comparable to scanf/printf.
To answer your question, printf is faster.
As already mentioned, writing to the terminal is almost definitely going to be slower. Why? depending on your OS, std::cout may use line buffering - which means each line may be sent to the terminal program separately. When you use std::endl rather than '\n' it definitely flushes the buffer.
So, in that case, cout is defined in the std namespace. Thus, std::cout states that is cout defined in the std namespace otherwise to use the definition of cout which is defined in std namespace. So, that std::cout is used to the definition of cout from std namespace.
std::cout
ultimately results in the operating system being invoked.
If you want something to compute fast, you have to make sure that no external entities are involved in the computation, especially entities that have been written with versatility more than performance in mind, like the operating system.
Want it to run faster? You have a few options:
Replace << std::endl;
with << '\n'
. This will refrain from flushing the internal buffer of the C++ runtime to the operating system on every single line. It should result in a huge performance improvement.
Use std::ios::sync_with_stdio(false);
as user Galik Mar suggests in a comment.
Collect as much as possible of your outgoing text in a buffer, and output the entire buffer at once with a single call.
Write your output to a file instead of the console, and then keep that file displayed by a separate application such as Notepad++ which can keep track of changes and keep scrolling to the bottom.
As for why it is so "time consuming", (in other words, slow,) that's because the primary purpose of std::cout
(and ultimately the operating system's standard output stream) is versatility, not performance. Think about it: std::cout
is a C++ library function which will invoke the operating system; the operating system will determine that the file being written to is not really a file, but the console, so it will send the data to the console subsystem; the console subsystem will receive the data and it will start invoking the graphics subsystem to render the text in the console window; the graphics subsystem will be drawing font glyphs on a raster display, and while rendering the data, there will be scrolling of the console window, which involves copying large amounts of video RAM. That's an awful lot of work, even if the graphics card takes care of some of it in hardware.
As for the C# version, I am not sure exactly what is going on, but what is probably happening is something quite different: In C# you are not invoking Console.Out.Flush()
, so your output is cached and you are not suffering the overhead incurred by C++'s std::cout << std::endl
which causes each line to be flushed to the operating system. However, when the buffer does become full, C# must flush it to the operating system, and then it is hit not only by the overhead represented by the operating system, but also by the formidable managed-to-native and native-to-managed transition that is inherent in the way it's virtual machine works.
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