setrecursionlimit() 함수에 관한 오해와 진실

ddongseop·2023년 1월 20일
0

Problem Solving

목록 보기
49/49

Python으로 PS를 할 때 최대 재귀 한도 깊이의 제한으로 인해 Recursion Error가 발생하는 것을 막기 위해 setrecursionlimit() 함수를 사용하곤 한다.

BOJ 11437번 LCA 문제 (https://www.acmicpc.net/problem/11437) 를 Python으로 풀던 중 제출한 코드가 Recursion Error가 났고, 평소와 같이 아래 코드를 추가하여 오류를 해결하고자 하였다.

sys.setrecursionlimit(10**6)

위의 코드를 추가했음에도 Python3로 제출했을 때 시간 초과가 발생하였고,
일반적으로 재귀를 사용하는 경우 JIT 컴파일을 도입하여 자주 쓰이는 코드를 캐싱하는 기능을 가진 PyPy가 빠르기 때문에 PyPy3로도 제출해보았다.

Python3 vs PyPy3: https://ralp0217.tistory.com/entry/Python3-%EC%99%80-PyPy3-%EC%B0%A8%EC%9D%B4

하지만 이번에는 메모리 초과가 발생하였는데, 다양한 기술 블로그들에서 PyPy3에서는 setrecursionlimit() 함수가 작동하지 않는다는 정보를 말하고 있었다.

그래서 setrecursionlimit() 함수를 삭제하고 다시 코드를 제출해보았는데, 이번에는 또 Recursion Error가 발생하였다.

혹시 최대 깊이를 10**5로만 설정하면 어떨지 하여 바꿔보았는데, Recursion Error도 발생하지 않고, 메모리 초과도 발생하지 않으며 정답 처리가 되었다.

이를 통해 깨달은 점은 아래와 같다.

  1. PyPy3에서도 setrecursionlimit() 함수가 대략적으로 동작한다.
    http://doc.pypy.org/en/latest/cpython_differences.html 을 읽어보면
    "sys.setrecursionlimit(n) sets the limit only approximately, by setting the usable stack space to n * 768 bytes. On Linux, depending on the compiler settings, the default of 768KB is enough for about 1400 calls."
    라는 문구가 있다.

  2. 다만 최대 깊이를 필요한 만큼만 설정해주어야 메모리 초과가 발생하지 않는다.

  3. 기술 블로그에 나와 있는 정보들을 너무 믿지 말고, 관련 공식 문서를 열람하는 것이 정확하다.

BOJ 커뮤니티에서도 똑같은 주제로 토론하는 사람들이 있는 것을 발견하였다. https://www.acmicpc.net/board/view/35748

Python으로 PS를 준비한다면, 이런 에매한 부분들을 정확히 파고들 필요가 있어 보인다..

0개의 댓글