BASE = 11172# number of Korean Unicode MAX_CHAR = 40# number of chars per line MAX_LINE = 40# number of lines per page MAX_PAGE = 410# number of pages per book
NUMBER_OF_BOOK = BASE**(MAX_CHAR*MAX_LINE*MAX_PAGE) # number of possible books NUMBER_OF_PAGE = BASE**(MAX_CHAR*MAX_LINE) # number of possible pages
book = random.randrange(NUMBER_OF_BOOK) # which book do you want to read? page_num = 200# which page do you want to read?
divisor = NUMBER_OF_PAGE**page_num book //= divisor # cut off front pages book %= (divisor**2) # cut off behind pages result = '' for _ inrange(MAX_CHAR*MAX_LINE): book, char = divmod(book, BASE) result += chr(char+44032) print(result)
보여줄 페이지 부분만큼 자르는 15, 16번째 줄에서 50초 가량 잡아먹는다. 페이지를 자르지 않으면 아래 for 문에서 그 이상의 시간이 발생한다. 수가 워낙 크기에 나눗셈 연산이 버거운 듯 보였다. 최적화의 여지가 없어보였다.
퍼포먼스 개선을 위해서 11172진법 시스템을 먼저 개발하기로 했다. 배열을 이용해 각 자리의 수들을 따로 따로 담는다면 문자들을 얻기 위해 나누기 연산이나 나머지 연산을 할 필요없이, 슬라이싱으로 자르고 인덱싱으로 문자를 얻어내면 그만이기에 10진법 환경보다는 속도가 빠르리라 예상했다.
기능은 2진법, 8진법, 1739진법 11172진법등등 어떤 n진법이나 구현할 수 있으면서, n진법에서 원하는 자리수를 수학적 연산없이 뽑아낼 수 있다는 것.
# withBase11172.py from base11172 import Base11172 import random
BASE = 11172# number of Korean Unicode MAX_CHAR = 40# number of chars per line MAX_LINE = 40# number of lines per page MAX_PAGE = 410# number of pages per book
LENGTH_OF_BOOK = MAX_CHAR*MAX_LINE*MAX_PAGE # length of book LENGTH_OF_PAGE = MAX_CHAR*MAX_LINE # length of page
# which book do you want to read? book = Base11172([random.randrange(BASE) for _ inrange(LENGTH_OF_BOOK)], 1) page_num = 200# which page do you want to read?
page = book[page_num*LENGTH_OF_PAGE:(page_num+1)*LENGTH_OF_PAGE] # slice page result = '' for char in page: result += chr(char+44032) print(result)
성능 차이는 대충 요정도
1 2
withoutBase11172.py: 3209 function calls in 56.617 seconds withBase11172.py: 2930449 function calls (2930448 primitive calls) in 1.784 seconds
남 보여주기에 매우 부끄러운 코드를 조금은 덜 부끄럽게 손보고 Github에 업로드했다. 문서화는 둘째치고 아직 기능도 다 구현안한 상태지만 알고리즘 같은거 공부한다든지 계속 가지고 놀기에는 꽤 괜찮은 프로젝트 주제처럼 보인다. LOBK 말고도 범용적으로 쓰일 수 있을지는 아직 모르겠다.