Goで高速にLog10を計算する

数値を右揃えあるいは0詰めして表示するのはまれによく遭遇するタスクです。 fmt.Printfには出力幅を指定する機能がありますが、幅をいくつにとればよいか、 言い換えれば「一番大きな数値の、桁数はいくつか?」は、プログラマーが計算しなければなりません。

従来、そのような用途には標準ライブラリのmath.Log10が使用されていました。 しかしながら、math.Log10float64を扱う関数であるため、 intint64の幅を計算したい場合(テキストを行番号つきで出力する場合などがそうですね)には、多倍長浮動小数点数計算を行うのは過剰であり時間の浪費です。

そこで、整数に最適化した、Log10の実装を作成し、githubに公開いたしました。

func Log10

func Log10(n uint64) int

Log returns the decimal logarithm of n. Log10(0) = 0 as a special case. Log10 must very faster than math.Log10 in the standard library.

https://github.com/doloopwhile/go-fastlog

f:id:doloopwhile:20140807133615p:plain

19.4 ns/op -> 6.63 ns/op なんと!math.Log10に比べ192%もの高速化が実現されました!

次に整数の桁数を求めたくなった時は、math.Log10ではなく、fastlog.Log10を使いましょう!