0

I am trying to understand buffer, endl vs \n and why the latter is more efficient than endl.

Specifically, I am reading this https://www.geeksforgeeks.org/buffer-flush-means-c/

The following code is supposedly output 1,2,3,4,5 at once

#include <iostream>
#include <windows.h>
using namespace std;


int main()
{
   for (int i = 1; i <= 5; ++i)
   {
      cout << i << " " ;
     Sleep(300);
   }
     cout << endl;

   return 0;
}

whereas the following will output each integer one at a time:

#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
   for (int i = 1; i <= 5; ++i)
   {
      cout << i << " " << flush;
      Sleep(300);
   }
   return 0;
}

However, both looks exactly the same during the time of execution, they appear one a time. Is my understanding wrong?

I'm also confused why endl is less efficient compared to \n.

From what I read, endl adds a \n and then flushes.

Isn't this more efficient, since it waits for the buffer to be full then output everything at once, compared to \n?

Please correct my flawed understanding, thank you.

relime2543
  • 103
  • 1
  • 6
  • Just inverse: `'\n'` just adds a character to the buffer, not necessarily flushing, `std::endl` forces printing the buffer to screen. – Aconcagua May 21 '21 at 05:50
  • If I understood you right you wonder that the output is done immediately even without flushing explicitly? It's funny because I found another question which is asking exactly the opposite: [SO: C++ sleep() function works not as expected](https://stackoverflow.com/q/42172387/7478597). So, it may depend on your platform, IDE, console or whatever that everything is printed immediately - even without flushing explicitly. – Scheff's Cat May 21 '21 at 05:51
  • Side note: https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice – Aconcagua May 21 '21 at 05:51
  • @Scheff `Sleep` (with initial capital letter) hints to windows platform – likely MSVC (bad choice in my eyes...). I wouldn't be surprised if MS decided to flush buffers on call to that function... – Aconcagua May 21 '21 at 05:53
  • your question is discussed here. https://stackoverflow.com/questions/213907/stdendl-vs-n – dixit_chandra May 21 '21 at 05:55
  • 1
    *Isn't this more efficient, since it waits for the buffer to be full then output everything at once, compared to \n?* I think you have that backward. With the flush, `endl` immediately dumps the buffer into the underlying media (which may be expensive). `'\n'` does not have to flush (but some implementations will because it suits that media) and may fill up the whole buffer before before sending it to the media. – user4581301 May 21 '21 at 05:56
  • About flushing on `Sleep`: If so, it is *not* [documented](https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleep) (again wouldn't surprise). – Aconcagua May 21 '21 at 06:00
  • Just to assure correct reading of the geeks for geeks text: `at once` means *after* waiting all of the five seconds. By the way, have you tried the same with `chrono` library as in the example? It might not change anything, if `chrono` itself maps to `Sleep`, too, or is implemented the same way. But might be worth a try at least. If you see a change, then `Sleep` function flushes. – Aconcagua May 21 '21 at 06:06
  • you arent that much in control of when the buffer is flushed. `std::endl` forces a flush, but that does not imply that without it the buffer is not flushed – 463035818_is_not_an_ai May 21 '21 at 06:16
  • btw `#include ` makes your code unnecessarily unportable. See here for how to sleep: https://stackoverflow.com/questions/4184468/sleep-for-milliseconds (not the accepted, but the most voted answer) – 463035818_is_not_an_ai May 21 '21 at 06:20
  • As noted in the duplicate question: *`\n` will also flush if the output is connected to an interactive device, like a terminal.* – selbie May 21 '21 at 07:16

1 Answers1

0

You will clearly see the difference if you run the following code:

#include <iostream>
#include <unistd.h>
using namespace std;
int main()
{
   for (int i = 1; i <= 5; ++i)
   {
      cout << i << " " << flush;
      usleep(300000);
   }
   cout<<"\n";
   for (int i = 1; i <= 5; ++i)
   {
      cout << i << " " ;
     usleep(300000);
   }
    cout << endl;
     
   return 0;
}

std::endl is equivalent to using "\n" and flush together.

If your program is stable then simply use "\n" else go for std::endl. "\n" is more efficient in terms that it does not force the buffer to be flushed right then.

Also in your code, you might now be able to see the difference because you are using Sleep() which takes input in milisec, so try with greater value.

HARSH MITTAL
  • 750
  • 4
  • 17