C++ Fast pow Function
Precaculated Exponentiation Table
constexpr 함수와 constexpr static 변수를 사용하여 컴파일 타임에 계산하는 global객체 하나를 생성한다. constexpr 함수로 실제 값을 계산하고, index_sequence를 사용해 해당 값으로 배열을 초기화 한다. 여기에 나와있는 index_sequence를 사용한다면 C++11에서도 사용할 수 있다. 배열의 크기는 해당 타입이 나타낼 수 있는 최대 수의 log_10 값 이어야 하는데, 정수라면 std::numeric_limits에 있는 digits10 값을 이용하면 된다. (부동소수점의 digits10은 fraction 부분에 해당하는 값이므로 따로 계산해야 한다.) 이를 코드로 표현하면 다음과 같다.
pow10_fast_tmp는 constexpr 함수이므로 컴파일 타임에 수행될 수 있다. 즉,
std::array<int, pow10_fast_tmp<size_t>(3)> arr
와 같이 사용할 수 있다.
벤치 마크
위에서 생성한 테이블을 활용한 pow 계산 (사실상 접근)과 실제 값 계산을 비교해 보자. 다음과 같은 테스트 코드를 통해 수행시간을 확인하였다.
결과
i7-8700 환경에서 다음과 같은 옵션으로 컴파일 후 실행하였다. (clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final))
clang++ -std=c++14 -O2 pow_table.cpp
100000000 번 pow를 했을 때, std::pow의 경우 3000ms 근처, 미리 계산한 테이블의 경우 30ms 정도가 소요되었다.
TODO: Table for Floating Point Types
수정 후 double 타입 등에서도 동작할 수 있게 해보자.