이번 시간에는 파이썬의 setrecursionlimit에 대해 알아봅시다.

 


 설명을 보시면, 딱히 어렵지는 않습니다. 인터프리터의 maximum stack depth를 늘려줍니다. 스택 트레이스 할 때 그 뎁스를 의미합니다. 이 뎁스는 재귀 호출과 관련이 깊습니다.

 

 예를 들어, 20000번째 피보나치 수를 M으로 나눈 결과를 재귀함수로 구한다고 생각해 봅시다. 메모이 제이션까지 적용한다면 위와 같이 구할 수 있습니다. dp[x]가 -1이 아닐 때에는 그냥 dp[x]를 리턴해 주고, 아니라면 x-1번째 피보나치와 x-2번째 피보나치를 더한 다음에 M으로 나눈 나머지를 리턴합니다.

 

 

 그런데, RecursionError가 뜹니다. 이는, depth가 너무 많이 깊어져서 smash가 나지 않게 하기 위해서입니다. 이 제한을 푸는 것이 setrecursionlimit 메서드입니다. 그런데, highest possible limit는 platform dependent 하다는 말은 무슨 이야기일까요? 일단 스택 깊이 제한을 3만까지 풀어보고, 2만번째 수를 구해 보도록 하겠습니다.

 


 sys.setrecursionlimit(30000)은 깊이 제한을 3만으로 늘린다는 의미입니다. 리눅스 환경에서 이 프로그램을 돌려 보겠습니다.

 

 

 437241455가 나옵니다. 정상적으로 수행이 되네요.

 

 반면에 윈도우는 어떤가요? 같은 프로그램입니다. 실행을 시켜보도록 하겠습니다.

 

 

 그러면, 0xC00000FD가 나오면서, 비정상 종료가 되는데요. 이는 스택 크기가 넘어갔다는 의미입니다. 플랫폼 dependent 하다는 게 이런 의미가 아닐까 싶습니다. 어떤 환경에서는 먹힐 수 있는데, 어떤 환경에서는 안 먹힐 수도 있다는 것입니다. 그래서, (제 생각이지만) 사용할 때 조심해야 하는 메서드 중 하나가 아닐까 싶어요.

 


 그러면 어떻게 개선하면 좋을까요? 사실, 피보나치 수를 구하기 위해서, 재귀 호출을 할 필요는 없습니다.

 

 

 x번째 수를 알기 위해, x-1번째와 x-2번째만 알면 되므로, 재귀 부분을 반복문으로 고칠 수 있습니다.

 

 437241455가 나왔습니다. 재귀 호출을 쓰지 않고, 2만번째 피보나치 수를 10억 7로 나눈 나머지를 구할 수 있게 되었습니다.