minzzl

꿀팁 / Python 빠른 입출력 본문

Algorithm/기타 공부

꿀팁 / Python 빠른 입출력

minzzl 2022. 12. 2. 15:29
728x90
반응형

지난 번, 빠른 입력을 위해 sys 모듈을 import 하는 방법을 알아보았습니다.

그런데 더 간단하고 쉬운 방법을 알게되어 소개해볼까합니다.

 

파이썬으로 알고리즘 문제를 푸는 것이, 구현에 공을 들이지 않아도 된다라는 장점도 있지만,

자꾸만 시간초과 문제로 골머리를 앓게 만드는 것 같습니다 . . .^^

 

서칭을 해보니 다음과 같은 템플릿을 사용하면 이 문제를 해결 할 수 있었습니다.

 

import sys, os, io, atexit

input = lambda: sys.stdin.readline().rstrip('\r\n')
stdout = io.BytesIO()
sys.stdout.write = lambda s: stdout.write(s.encode("ascii"))
atexit.register(lambda: os.write(1, stdout.getvalue()))

해당 코드를 상위에 복붙한 후 input 함수와 print 함수를 원래 쓰던대로 쓰면 속도가 현저히 개선됩니다.

 

Fast Input

 

input()으로 10만 개의 글자를 한 번에 읽는 것보다, 한 개의 글자를 10만 번 읽는 것이  훨씬 느립니다. 즉, 읽는 양의 문제가 아닌 읽는 횟 수에 따라 현저히 느려집니다. input이 이렇게 실행 overhead가 큰 이유는 prompt parameter의 존재 때문과, stderr을 매번 flush 하기 때문, 또 syscall을 위해 매번 tty를 확인하기 때문이라고 추측된다고 합니다.

 

그러나 알고리즘 문제를 풀 때에는 prompt나 stderr 같은 것을 쓸 필요가 없습니다. 입력된 값을 읽어오는 그 기능의 핵심만 사용하는 것이 전부입니다. 따라서 sys.stdin 으로 부터 바로 readline 하여 속도를 향상 시킬 수 있습니다.

 

readline은 input과 달리 개행 문자를 자동으로 없애 주지는 않습니다. 따라서 문제가 string을 받는 것을 요구하면 rstrip를 이용하여 개행문자를 제거해주어야합니다. 다만 입력이 숫자라면 개행문자를 없앨 필요가 없습니다.

 

Fast Output

 

print()도 마찬가지입니다. 출력하는 문제가 아니라 출력하는 횟수가 문제가 된다고 합니다. 그래서 따로 무언가를 import 하지 않더라도 속도 향상을 이루어낼 수 있습니다. 내용을 하나의 list에 모두 합쳐 마지막 단 한번에 print하는 것입니다. 

 

 

 

 

 

 

* 아래의 글을 참고하여 작성하였습니다.

https://yumtam.medium.com/python-3-pypy-%EB%B9%A0%EB%A5%B8-%EC%9E%85%EC%B6%9C%EB%A0%A5-8ffde8dd7a90

 

728x90
반응형