• 性能测量

  在很多情况之下,通过分析代码是很难确定某个模块性能好坏的。请看下面的例子,你觉得哪一个函数性能最优?

 //斐波那契数
package fib import "math" //递归方式
func Fib(n int) int {
if n < {
return n
}
return Fib(n-) + Fib(n-)
} //迭代方式
func Fib2(n int) int {
if n < {
return n
}
a :=
b :=
c :=
for i := ; i < n; i++ {
c = a + b
a = b
b = c
}
return c;
} //公式求解
func Fib3(n int) int {
gh5 := math.Sqrt()
pow := math.Pow
f := (float64)(n)
return (int)(math.Ceil((pow(+gh5, f) - pow(-gh5,f)) / (pow(2.0, f) * gh5)))
}
上面的代码提供了3种求斐波那契数的方法,毫无疑问第一种方式是最不可取的。但是第二种和第三种方式到底哪一个性能更好呢?好多人可能会说是第三种。口说无凭,写个测试用例看看:
 package fib_test

 import (
"testing"
"goperformance/fib"
) func Test_Fib(t *testing.T) {
println(fib.Fib())
} func Test_Fib2(t *testing.T) {
println(fib.Fib2())
} func Test_Fib3(t *testing.T) {
println(fib.Fib3())
} func Benchmark_Fib(b *testing.B) {
for i := ; i < b.N; i++ {
fib.Fib(i%)
}
} func Benchmark_Fib2(b *testing.B) {
for i := ; i < b.N; i++ {
fib.Fib2(i%)
}
} func Benchmark_Fib3(b *testing.B) {
for i := ; i < b.N; i++ {
fib.Fib3(i%)
}
}

执行 #go test -bench=. -v

 === RUN   Test_Fib

 --- PASS: Test_Fib (.63s)
=== RUN Test_Fib2 --- PASS: Test_Fib2 (.00s)
=== RUN Test_Fib3 --- PASS: Test_Fib3 (.00s)
PASS
Benchmark_Fib- ns/op
Benchmark_Fib2- 13.4 ns/op
Benchmark_Fib3- ns/op
ok goperformance/fib .086s

很明显第二种方式比第三种方式要快100多倍。性能测量为我们编写高性能的go程序提供了可靠的依据。

  • 性能分析

1,使用标准库runtime/pprof

 package main

 import (
"goperformance/fib"
"flag"
"log"
"os"
"runtime/pprof"
) var cpuprofile = flag.String("cpuprofile", "cpu.prof", "write cpu profile to file") func main() {
flag.Parse()
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
println(fib.Fib())
println(fib.Fib2())
println(fib.Fib3())
}

编译并执行程序获得性能分析文件

 \src\goperformance>go build
\src\goperformance>goperformance.exe \src\goperformance>go tool pprof goperformance.exe cpu.prof
Entering interactive mode (type "help" for commands)
(pprof) web
(pprof)

在web中展示出来的分析结果如下:

2,使用github.com/pkg/profile

profile包实际上是对runtime/pprof的封装,使用起来更加友好

 package main

 import (
"goperformance/fib"
"github.com/pkg/profile"
) func main() {
defer profile.Start().Stop() //可以通过不同的参数确定是cpu性能分析还是内存使用分析
println(fib.Fib())
println(fib.Fib2())
println(fib.Fib3())
}

运行程序后在缓存自动生成一个临时文件,这个文件就是上一种方式中的cpu.prof文件。接下来的操作就和第一种方式一样。

 

最新文章

  1. 1Z0-053 争议题目解析699
  2. Codeforces Round #251 (Div. 2) A - Devu, the Singer and Churu, the Joker
  3. Harris角点(转载)
  4. 统计机器翻译(SMT)步骤总结
  5. 【转】VS调试技巧
  6. 成为一名优秀的C程序员
  7. HttpDNS的坑以及一个针对安卓不太完善的测试方案
  8. SQL update select
  9. Cassandra标准列和超级列
  10. Dubbo 消费者
  11. vue实现点击关注之后及时更新列表
  12. 小希的迷宫---hdu1272
  13. redis未授权访问批量验证脚本编写[python]
  14. thread_indent
  15. 关于JDBC PreparedStatement
  16. jQuery动态星级评分效果实现方法
  17. Linux网络编程:一个简单的正向代理服务器的实现
  18. spfile 和用户环境变量 和export
  19. apktool、dex2jar、jd-gui的区别及详解
  20. 第19章 通讯的基本概念—零死角玩转STM32-F429系列

热门文章

  1. idea2018.2.4的安装激活与热部署插件JRebel的激活方法
  2. 在Matlab中安装使用libsvm详细步骤(附图)
  3. Python自动化开发 - Django【基础篇】
  4. [jquery] 遮罩弹窗,点击遮罩弹窗自动隐藏
  5. Linux分区之parted命令
  6. CentOS7下启用网卡
  7. 背水一战 Windows 10 (48) - 控件(集合类): FlipView
  8. Servlet初步认知
  9. ionic3.x angular4.x ng4.x 自定义组件component双向绑定之自定义计数器
  10. cad.net的undo返回操作