문제 상황
현재 하고 있는 회사 프로젝트에서는 굉장히 큰 수를 많이 자주 다룬다.
123124333099330999999999999999999999999999999999999999999999999999993309999999999999999999999999999999999999999999999999999933099999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 등의 숫자를
아무렇지 않게 곱하고 , 나누고 하는 “Inflation Game” 의 장르기 때문이다.
문제는 , 현재 사용하고 있는 오픈소스 BigInteger 라이브러리가 굉장히 무겁다는 것이다.
( 왜냐면 유니티 현 .net 버전으로는 C# 의 내장 BigNumber 를 사용할 수 없기 때문이다. )
특히, 빅인티저 숫자를 UI 등에서 사용하거나 로컬 저장하기 위해 사용하는 BigInteger.ToString 이 굉장히 무거워서
매번 프레임 드랍과 각종 이슈들이 나타났다.
해결
다행이도 해당 BigInteger 내부에는 RightShift ,LeftShift 같은 비트연산도 구현되어 있었다.
그래서 일정 이상으로 큰 수를 String 으로 바꿀 때 , 수를 RightShift 연산을 n번 해서 자릿수를 크게 줄였다.
그리고 이 수를 Log 씌우고 이를 log2 * n 을 곱한 수와 더해서
가수 부분을 Mathf.Pow(10, ${가수}}) 하면
앞자리수 일부를 알 수 있다.
그걸 앞자리에 넣고 다시 n 을 이용해서
” 1.23 A “ 뭐 이런 식의 스트링으로 산출해줬다 !
ToString 은 매번 자리수 만큼 나누기를 시연하는 로직으로 짜져 있었기 때문에
굉장한 성능 향상이 가능했다.
테스트 해서
그래프로 뽑아보면 ToString 으로 만들면 O(n^2) 같이 증가하지만
이 방법으로하면 O(n) 그래프로 나온다.
감상
수학이 미래다..? ㅎㅎ
앞으로도 수학 공부를 게을리 하지 말자.