Блог пользователя deepanshujain088

Автор deepanshujain088, история, 4 года назад, По-английски

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://codeforces.net/problemset/problem/368/B

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

  • Проголосовать: нравится
  • +17
  • Проголосовать: не нравится

»
4 года назад, # |
Rev. 3   Проголосовать: нравится +38 Проголосовать: не нравится

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 года назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится

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

»
4 года назад, # |
  Проголосовать: нравится -8 Проголосовать: не нравится

add cout.tie(0);

  • »
    »
    4 года назад, # ^ |
      Проголосовать: нравится +6 Проголосовать: не нравится

    Please tell me that you are trolling.

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

    • »
      »
      »
      4 года назад, # ^ |
        Проголосовать: нравится +8 Проголосовать: не нравится

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

    • »
      »
      »
      5 месяцев назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      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 месяцев назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

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

      • »
        »
        »
        »
        5 месяцев назад, # ^ |
        Rev. 2   Проголосовать: нравится +11 Проголосовать: не нравится

        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 месяцев назад, # ^ |
            Проголосовать: нравится -18 Проголосовать: не нравится

          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 месяцев назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится

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

            • »
              »
              »
              »
              »
              »
              »
              5 месяцев назад, # ^ |
                Проголосовать: нравится 0 Проголосовать: не нравится

              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 месяцев назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится

            and why my comment got downvoted?

            • »
              »
              »
              »
              »
              »
              »
              5 месяцев назад, # ^ |
                Проголосовать: нравится +4 Проголосовать: не нравится

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