peltorator's blog

By peltorator, 3 years ago, In English

When you use C++ and the input is really big you can't just use cin and cout. You need to speed up it with

ios::sync_with_stdio(0);
cin.tie(0);

Someone argues that the second line is unnecessary but it's not true. if the input and output alternate then adding the second line makes I/O more than twice faster. But then... Someone argues that we also need to use cout.tie(0).

I personally never use this and I don't know any case where it can help. So my question for today is the following: "Is there any case where we actually need cout.tie? Or is it completely useless?"

  • Vote: I like it
  • +276
  • Vote: I do not like it

| Write comment?
»
3 years ago, # |
  Vote: I like it +90 Vote: I do not like it

I have read several comments related to it by a user -is-this-fft- and I quote "cout.tie(NULL) does literally nothing because cout is already tied to NULL", "It sounds very strange when you consider what tie does. Every input or output stream in C++ is tied to an ostream or to null. Tyig cin to null means it's not tied to cout anymore which can speed things up. But cout is generally already tied to null."

Link to the comments — https://codeforces.com/blog/entry/87419?#comment-756655, https://codeforces.com/blog/entry/83672?#comment-709924

  • »
    »
    3 years ago, # ^ |
    Rev. 2   Vote: I like it +479 Vote: I do not like it

    Yes, you are correct.

    I think it would be good to reiterate what tie does because I see a lot of people copying these lines with only a vague understanding of what they do.

    Every stream in C++ is tied to an output stream, which can be null.

    What does this mean? First of all, it's important to understand that when you write std::cout << "asdf", it is not necessarily immediately printed on the screen. It turns out that it is much better (in terms of performance) to collect it into a buffer and then, at some point, flush the buffer — i.e. empty its contents to the screen (or file, or any other "device"), all at once.

    But now, consider the following. You are developing a console application and write something like:

    1 std::cout << "Please enter your age: ";
    2 int age;
    3 std::cin >> age;
    

    What would happen if std::cout didn't get flushed before line 3? The program would expect a reply from the user, but the user hasn't even had a chance to read the question. In an application like this, it would be a good idea if std::cout was somehow automatically flushed when we try to read from std::cin.

    And this is exactly the problem tie solves. If you have two streams fin and fout, and fin is tied to fout, then fout is automatically flushed when you try to read from fin. So what are the defaults? What is tied to what? Quoting the C++ reference:

    By default, the standard narrow streams cin and cerr are tied to cout, and their wide character counterparts (wcin and wcerr) to wcout. Library implementations may also tie clog and wclog.

    Now it becomes clear why people recommend using cin.tie(0) in competitive programming. Suppose you are solving a query problem like this.

    1 MyAwesomeDataStructure ds;
    2 for (int i = 0; i < queryc; i++) {
    3   Query q;
    4   cin >> q;
    5   cout << ds.solve(q) << '\n';
    6 }
    

    If you didn't use cin.tie(0), we would flush cout every time we hit line 4; this is essentially as bad as writing endl on line 5. Concerns about the user not seeing the question are also irrelevant now because we are given the entire input at once.

    The reference doesn't explicitly say that cout isn't tied to anything, but on every C++ compiler I tried, cout << cout.tie() << endl; outputs 0. Also, even if you are using some strange compiler that ties cout to some other stream sout, you would only notice the performance hit if you wrote a lot to sout which doesn't really happen in competitive programming.

    So yes, cout.tie(0) doesn't do anything and in some sense it's a sign that the user doesn't understand cin.tie(0) very well either.

    • »
      »
      »
      3 years ago, # ^ |
        Vote: I like it -140 Vote: I do not like it

      While you are probably right in the sense that what you are saying is correct, I think it is a wrong way to understand cin.tie(0) in competitive programming. And the last line from your comment for me proves that you are wrong. The last line reads like the fact that "the user doesn't understand it" is bad somehow. I don't agree.

      cin.tie(0) is just a bullshit line to make cin faster. I don't give a fuck what it does inside or how it works or why it even exists. The same with using namespace std — it's just something that stupid computer needs to understand you, that's it.

      • »
        »
        »
        »
        3 years ago, # ^ |
          Vote: I like it +296 Vote: I do not like it

        Well, I don't think it is very bad to not know what tie does. Still, I prefer to know these things to prevent any unpleasant surprises.

        • »
          »
          »
          »
          »
          3 years ago, # ^ |
            Vote: I like it +446 Vote: I do not like it

          Sorry, you answered a question that Um_nik wasn't interested in knowing the answer to. Please apologize for wasting his time.

          • »
            »
            »
            »
            »
            »
            3 years ago, # ^ |
              Vote: I like it -205 Vote: I do not like it

            hi

          • »
            »
            »
            »
            »
            »
            3 years ago, # ^ |
              Vote: I like it +10 Vote: I do not like it

            for me Um_nik is a legend who doesn't gives a F about anything and when he does he F's that thing

          • »
            »
            »
            »
            »
            »
            3 years ago, # ^ |
              Vote: I like it +100 Vote: I do not like it

            No, it was an interesting read. Useless, but interesting.

            • »
              »
              »
              »
              »
              »
              »
              3 years ago, # ^ |
                Vote: I like it +10 Vote: I do not like it

              Classic um_nik way lol : useless but interesting

            • »
              »
              »
              »
              »
              »
              »
              3 years ago, # ^ |
                Vote: I like it +20 Vote: I do not like it

              Pretty much the same as CP. Right ?

              • »
                »
                »
                »
                »
                »
                »
                »
                3 years ago, # ^ |
                  Vote: I like it +43 Vote: I do not like it

                That depends on how you define usefulness.

        • »
          »
          »
          »
          »
          3 years ago, # ^ |
          Rev. 2   Vote: I like it +18 Vote: I do not like it

          Thanks. Now I completely understand why using tie would recieve Idleness Limit Exceeded for those interactive problems. :D

      • »
        »
        »
        »
        3 years ago, # ^ |
          Vote: I like it +21 Vote: I do not like it

        Um_nik, a guy with zero haters

    • »
      »
      »
      3 years ago, # ^ |
        Vote: I like it +66 Vote: I do not like it

      Why do we still need to flush the buffer for interactive problems if one has not added cin.tie(0)?

      • »
        »
        »
        »
        3 years ago, # ^ |
          Vote: I like it +44 Vote: I do not like it

        You know, I'm starting to think that you don't. I just went and resubmitted some solved interactive problems, removing any endl (those flush the output) and making sure there is no cin.tie(0). All of them got Accepted. Then I added cin.tie(0) and got (I think for the first time ever) the Idleness Limit Exceeded verdict.

    • »
      »
      »
      3 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Your answer is very good but I mistakenly voted against, I'm sorry...

  • »
    »
    3 years ago, # ^ |
      Vote: I like it +26 Vote: I do not like it

    Thank you!

»
3 years ago, # |
  Vote: I like it -86 Vote: I do not like it
Do you agree?
  • »
    »
    3 years ago, # ^ |
      Vote: I like it +1 Vote: I do not like it

    I've seen your comments a lot lately on a lot of blogs. Now I think you're the one seeking +ve contribution.

»
3 years ago, # |
  Vote: I like it +33 Vote: I do not like it

cout.tie(0) is not necessary, because by default cin ties with cout, but cout ties with nullptr so it's basically does nothing.

You can check it by code:

Spoiler
»
3 years ago, # |
  Vote: I like it +8 Vote: I do not like it

If you do not properly understand, what cin.tie(smth) and cout.tie(smth) do, you might want to write them all together. It doesn't slow your code down (does it?) and it decreases the chance you mix them up and write only cout.tie(nullptr) instead of cin.tie(nullptr).

I have somehow memorized that cout.tie(nullptr) is useless and excluded it from my pre-written pattern. I also do not write it in competitions that doesn't allow participants to use pre-written code. I don't know a simple way to remember, which string is useless (is cin kind of tied to cout, or is it the opposite?). So, I have just realised, it is better to write both of them.

  • »
    »
    3 years ago, # ^ |
      Vote: I like it +18 Vote: I do not like it

    You're absolutely right. This question isn't about practice usage. I'm just interested in this.

»
3 years ago, # |
  Vote: I like it +1 Vote: I do not like it

Should we use cin.tie(0); in Interactive Problems where next input depends on what we print using cout?

  • »
    »
    3 years ago, # ^ |
      Vote: I like it +5 Vote: I do not like it

    I think there isn't actually any need for fast IO in interactive problems most of the time because we use flush and it's really slow. But at the same time, there is no reason not to use fast IO always.

»
3 years ago, # |
  Vote: I like it -49 Vote: I do not like it

"Once and forever".... What a joke)
There still exists people that don't know that comparator must return true if and only if lhs is strictly less than rhs.

cout.tie in competitive programming is useless AFAIK. But it is usefull when you need to guarantee that you write in tied output strictly before cout. But I don't know when there is need for it;)

»
3 years ago, # |
  Vote: I like it +1 Vote: I do not like it

Well, I also had a question related to this, that Is their any difference btw ios_base::sync_with_stdio(false); cin.tie(NULL); and cin.tie(0)->sync_with_stdio(0);(i saw this in Benq's template)

  • »
    »
    3 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Both do same
    But I'd say first is preferable since second way is confusing. sync_with_stdio is static method and it supposed to be called as static not as member of cout.

»
4 months ago, # |
  Vote: I like it 0 Vote: I do not like it

I am not sure of the logic behind it, but on a dp question on cses, my code gave runtime error without cout.tie(NULL) and got accepted when i added that line. https://cses.fi/paste/2f6f0fdf60a71e537a397d/ try submitting this same code without the cout.tie(NULL) line. it should give you a good idea