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

Автор IngaleAnkur10, история, 8 лет назад, По-английски

I tried this problem: https://codeforces.me/contest/1136/problem/D.
And came up with a solution similar to the solution in the editorial.
But I first submitted my Python code in both Python3 and PyPy3 and had TLE.
But when I submitted an ALMOST equivalent code in C++, it got accepted.
I wonder what's wrong in my python code or is it the compiler's/interpreter's doing?

Python Code 1 : https://codeforces.me/contest/1136/submission/51256343.
Python Code 2 : https://codeforces.me/contest/1136/submission/51262124.
C++ code: https://codeforces.me/contest/1136/submission/51257855.

Thanks in advance.

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

»
8 лет назад, скрыть # |
 
Проголосовать: нравится +36 Проголосовать: не нравится

Erm. Didn't you know that python runs slower than my grandma can crawl?

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

C++ is a lot faster than Python, so there are some problems which you can't solve in Python because it's not fast enough. I think that's the problem.

»
8 лет назад, скрыть # |
 
Проголосовать: нравится +37 Проголосовать: не нравится

Firstly pretty much always use pypy, it is a lot quicker than cpython in pretty much every way.

But the actual reason you get TLE is that the built in IO is very slow, especially when you have to read in multiple lines. One way to speed up the input is to do

input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

This reads in the input once, and then stores it in a stream. This one-liner will speed up your code immensely. With it your code runs in 1044 ms. There are also similar tricks you can do to speed up the output, but that wasn't necessary in this case.

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

    Thanks a lot! Also, can you give me some resources to other tricks to speed up io?

    • »
      »
      »
      8 лет назад, скрыть # ^ |
      ← Rev. 2  
      Проголосовать: нравится +8 Проголосовать: не нравится

      Most of the tricks I've been using just comes from me and c1729 trying out different methods. He has got a guide but I think it might be a bit outdated at this time.

      About IO, as a general rule of thumb, read the entire input in one go, write the entire output in one go. IO in python doesn't have to be slow, it is just the built in stuff that is slow. For example take this huge IO SPOJ problem. I've been able to do it in 0.10 s on pypy, while the quickest Java solution takes 0.17 s.

      I think that for input using

      input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

      will be good enough for most problems. And for output I think that using the pypy feature __pypy__.builders.StringBuilder is very good. Here is an example of using a string builder for output:

      import os,sys,__pypy__
      
      out = __pypy__.builders.StringBuilder()
      A = [137]*10000000
      for a in A:
          out.append(str(a))
          out.append(' ')
      
      if sys.version_info[0] < 3:
          os.write(1,out.build())
      else:
          os.write(1,out.build().encode())
      

      This takes around $$$420 \mathrm{ms}$$$ in pypy3 and $$$200 \mathrm{ms}$$$ in pypy2. (this is including the upstart time of around 100 ms that pypy got, so the print especially in pypy2 is super quick).

      The reason why pypy2 is quicker is that python 2 uses bytestrings but in python 3 they've switched from using bytestrings to using unicode-strings by default, this drastically slows down the IO. So in python3 you have to manually switch to using bytestrings in order to get fast IO (this is done with .encode(), but unfortunately encode is pretty slow). Bytestrings are also one of the reasons os.read is so quick.

      Using these methods you should see drastically better speeds in heavy IO problems.

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

        Thanks, updated the blog post with our most recent io techniques and some explanations.

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

        That was really helpful. Thank you so much.

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

        Hey, I use the following template (was copied from someone's solutions and is probably owned by you). Can you tell me if the following one is faster or the one you mentioned above ?

        Spoiler