golang 浮点数 取精度的效率对比

需求

    浮点数取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
}

 

  

 

posted @ 2017-06-15 19:01  莫名   阅读(4602)  评论(0编辑  收藏  举报