deepanshujain088's blog

By deepanshujain088, history, 4 years ago, In English

I have submitted the same algorithm with different input streams (cin and scanf) , I used ios_base::sync_with_stdio(false);cin.tie(NULL); with the cin and cout but still got a high difference in speeds?

Can somebody explain??

The problem link that I submitted is this one-- https://mirror.codeforces.com/problemset/problem/368/B

and my two differnt solutions are of 111556695 and 111568920 on Mar/31/2021.

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

| Write comment?
»
4 years ago, # |
Rev. 3   Vote: I like it +38 Vote: I do not like it

the issue arises from the cout and not the cin

cout << endl; is know to make code slower so i swapped that out for cout << '\n'; and this here my submission with that, 155ms or so

then i just tried using printf instead of cout this and it runs in 109ms or so

so the conclusion is (debug more) dont cout << endl as endl flushes the output which takes extra time. well even then printf still outdoes cout and scanf still outdoes cin. unless someone else can make some changes with this code and prove me wrong

EDIT: i submitted both codes again in c++17 and cout with '\n' and printf (with cin as input) both ran in 77ms whereas cout << with endl ran in 340~ms.

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

    Thanks bro, I googled but didn't get anything on this. But now I get where is the problem. :)

»
4 years ago, # |
  Vote: I like it +5 Vote: I do not like it

This issue and It's solution is very well explained by Priyansh31dec, Here is the link to it. Hope this helps.

»
4 years ago, # |
  Vote: I like it -8 Vote: I do not like it

add cout.tie(0);

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

    Please tell me that you are trolling.

    In case someone takes this seriously, cout.tie(NULL) does literally nothing.

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

      I wasn't but now I am gonna say I was

    • »
      »
      »
      5 months ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Sorry for Necroposting, But Here's the opposite what you have stated.

      In the problem E. Triple Operations, many submissions passed under Time Limit using cout.tie(NULL).

      Here is my TLE Solution without using cout.tie(NULL)

      And the same solution passes using cout.tie(NULL)

      • »
        »
        »
        »
        5 months ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        your solution shouldn't pass in the first place, maximum time complexity here is 2e5*1e4 = 2e9

      • »
        »
        »
        »
        5 months ago, # ^ |
        Rev. 2   Vote: I like it +11 Vote: I do not like it

        I'm at my wit's end. Can anyone else understand what's going on here? I made 5 submissions to this problem with and without cout.tie(NULL) to check that this is not simply a random fluctuation (my working hypothesis) and indeed, with cout.tie(NULL) it gets AC every time (albeit always >960 ms), without it never. Does Codeforces cache some results of submissions that generate identical binaries? Did I not make enough attempts?

        Here is the source code of .tie() that comes with winlibs GCC 13.2, which Codeforces uses. It is located at /mingw64/include/c++/13.2.0/bits.

              /**
               *  @brief  Fetches the current @e tied stream.
               *  @return  A pointer to the tied stream, or NULL if the stream is
               *           not tied.
               *
               *  A stream may be @e tied (or synchronized) to a second output
               *  stream.  When this stream performs any I/O, the tied stream is
               *  first flushed.  For example, @c std::cin is tied to @c std::cout.
              */
              basic_ostream<_CharT, _Traits>*
              tie() const
              { return _M_tie; }
        
              /**
               *  @brief  Ties this stream to an output stream.
               *  @param  __tiestr  The output stream.
               *  @return  The previously tied output stream, or NULL if the stream
               *           was not tied.
               *
               *  This sets up a new tie; see tie() for more.
              */
              basic_ostream<_CharT, _Traits>*
              tie(basic_ostream<_CharT, _Traits>* __tiestr)
              {
                basic_ostream<_CharT, _Traits>* __old = _M_tie;
                _M_tie = __tiestr;
                return __old;
              }
        

        The only thing that cout.tie(NULL) does is that it sets a protected variable _M_tie to NULL (the business with __old should get optimized away by the compiler). We can check by calling cout.tie() without arguments that _M_tie already is NULL.

        I can't check with winlibs (due to not having a Windows PC), but with normal GCC 13.2 at least, the only difference in the generated assembly is that cout.tie(NULL) generates a single instruction

          mov QWORD PTR std::cout[rip+224], 0
        

        and we know that there already is a 0 at that address. So the statement really should have no effect.

        My bet is that it's still some random fluctuation. Any Accepted submission with running time greater than (time limit) — 50 ms should be treated as "you got lucky". Codeforces actually reruns submissions that slightly exceed the time limit and takes the minimum.

        • »
          »
          »
          »
          »
          5 months ago, # ^ |
            Vote: I like it -18 Vote: I do not like it

          Hi.

          I think i found issue without cout.tie(NULL);

          i just removed #define int long long, and it got ac with 890 ms ->276266404 and here is same submission with #define int long long -> 276267213 and yeah main problem here was #define int long long, actually i think he got ACCEPTED with luck because i submitted solution with #define int long long but with cin.tie(null) and it got tl test 5 somehow -> 276270092.

          I belive that main problem here is not cin.tie(null); it is #define int long long.

          And i tested the same solution you submitted, and it got tl test 5 also, maybe because it is ongoing contest? but main problem is #define int long long

          • »
            »
            »
            »
            »
            »
            5 months ago, # ^ |
              Vote: I like it 0 Vote: I do not like it

            I always use #define int long long and in this question as well. It ran easily

            • »
              »
              »
              »
              »
              »
              »
              5 months ago, # ^ |
                Vote: I like it 0 Vote: I do not like it

              Show submission well in his submission he doing O(N) per query which is already bad. But compiler is not stupid so compiler optimizes it, i resended it without cin.tie(null);, and only when i remove #define int long long, it got AC? can you explain than, why without #define int long long it got AC but with #define int long long it got TLE

              • »
                »
                »
                »
                »
                »
                »
                »
                5 months ago, # ^ |
                  Vote: I like it 0 Vote: I do not like it

                274876226

                DP solution

                • »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  5 months ago, # ^ |
                    Vote: I like it 0 Vote: I do not like it

                  Well, we trying to understand why this solution works, i don't need DP solution

          • »
            »
            »
            »
            »
            »
            5 months ago, # ^ |
              Vote: I like it 0 Vote: I do not like it

            and why my comment got downvoted?

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

              The mystery is not really "how to fix this code". The mystery is "how does cout.tie(NULL) change anything at all".