需求
浮點數取2位精度輸出
實現
代碼
package main import ( "time" "log" "strconv" "fmt" ) func main() { threadCount := 100000 fa := 3.233667 time1 := TestFn(threadCount,fa,func(fa float64) string{ return strconv.FormatFloat(fa,'f',2,64) }) log.Printf("FormatFloat 耗時:%.4f ms",time1) time2 := TestFn(threadCount,fa,func(fa float64) string{ return fmt.Sprintf("%.2f",fa) }) log.Printf("Sprintf 耗時:%.4f ms",time2) } func TestFn(count int,fa float64,fn func(fa float64) string) float64{ t1 := time.Now() for i := 0; i < count; i++ { fn(fa) } t2 := time.Now() return t2.Sub(t1).Seconds()*1000 }
效率對比
測試 100次 (即threadCount賦值100,下面同理)
2017/06/15 18:50:17 FormatFloat 耗時:0.0452 ms 2017/06/15 18:50:17 Sprintf 耗時:0.0512 ms
測試 1000次
2017/06/15 18:50:43 FormatFloat 耗時:0.3861 ms
2017/06/15 18:50:43 Sprintf 耗時:0.4903 ms
測試 10000次
2017/06/15 18:50:58 FormatFloat 耗時:3.9688 ms
2017/06/15 18:50:58 Sprintf 耗時:5.2045 ms
測試 100000次
2017/06/15 18:51:20 FormatFloat 耗時:41.9253 ms
2017/06/15 18:51:20 Sprintf 耗時:51.8639 ms
測試 10000000次
2017/06/15 18:51:49 FormatFloat 耗時:3917.7585 ms
2017/06/15 18:51:54 Sprintf 耗時:5131.5497 ms
結論
strconv下的FormatFloat明顯快一些。fmt.Sprintf用到反射,效率不高,建議少用。
注意
golang下的浮點數存在2個問題:
1,運算時,計算結果不准
2,四舍五入時,用的是銀行舍入法,和其他語言四舍五入的值對不上
解決
//四舍五入 取精度 func ToFixed(f float64,places int) float64{ shift := math.Pow(10, float64(places)) fv := 0.0000000001 + f //對浮點數產生.xxx999999999 計算不准進行處理 return math.Floor(fv * shift + .5) / shift }