文档章节

go程序性能测量和分析

borey
 borey
发布于 2016/05/07 15:48
字数 626
阅读 174
收藏 5
  • 性能测量

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

//斐波那契数
package fib

import "math"

//递归方式
func Fib(n int) int {
    if n < 2 {
        return n
    }
    return Fib(n-1) + Fib(n-2)
}

//迭代方式
func Fib2(n int) int {
    if n < 2 {
        return n
    }
    a := 1
    b := 1
    c := 1
    for i := 2; i < n; i++ {
        c =  a + b
        a = b
        b = c
    }
    return c;
}

//公式求解
func Fib3(n int) int {
    gh5 := math.Sqrt(5)
    pow := math.Pow
    f := (float64)(n)
    return (int)(math.Ceil((pow(1+gh5, f) - pow(1-gh5,f)) / (pow(2.0, f) * gh5)))
}

上面的代码提供了3种求斐波那契数的方法,毫无疑问第一种方式是最不可取的。但是第二种和第三种方式到底哪一个性能更好呢?好多人可能会说是第三种。口说无凭,写个测试用例看看:

package fib_test

import (
    "testing"
    "goperformance/fib"
)

func Test_Fib(t *testing.T) {
    println(fib.Fib(40))
}

func Test_Fib2(t *testing.T)  {
    println(fib.Fib2(40))
}

func Test_Fib3(t *testing.T)  {
    println(fib.Fib3(40))
}

func Benchmark_Fib(b *testing.B) {
    for i := 0; i < b.N; i++ {
        fib.Fib(i%40)
    }
}

func Benchmark_Fib2(b *testing.B) {
    for i := 0; i < b.N; i++ {
        fib.Fib2(i%40)
    }
}

func Benchmark_Fib3(b *testing.B) {
    for i := 0; i < b.N; i++ {
        fib.Fib3(i%40)
    }
}

执行 #go test -bench=. -v

=== RUN   Test_Fib
102334155
--- PASS: Test_Fib (0.63s)
=== RUN   Test_Fib2
102334155
--- PASS: Test_Fib2 (0.00s)
=== RUN   Test_Fib3
102334155
--- PASS: Test_Fib3 (0.00s)
PASS
Benchmark_Fib-4              100          20280130 ns/op
Benchmark_Fib2-4        100000000               13.4 ns/op
Benchmark_Fib3-4        10000000               123 ns/op
ok      goperformance/fib       6.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(40))
	println(fib.Fib2(40))
	println(fib.Fib3(40))
}

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

\src\goperformance>go build
\src\goperformance>goperformance.exe
102334155
102334155
102334155
\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(40))
	println(fib.Fib2(40))
	println(fib.Fib3(40))
}

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


© 著作权归作者所有

共有 人打赏支持
borey
粉丝 27
博文 55
码字总数 31182
作品 0
深圳
程序员
私信 提问
用 dotTrace 进行性能分析时,各种不同性能分析选项的含义和用途

版权声明:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:http://blog.csdn.net/wpwalter/)...

walter lv
11/28
0
0
> 读书笔记之Java性能优化

<<代码大全>> 25.6 代码调整方法总结: 1 用设计良好的代码来开如软件,从而使程序易于理解和修改 2 如果程序性能很差: a 保存代码的可运行版本,这样你才能回到“最近的已知正常状态” b 对系...

周翔
2016/01/30
164
0
服务器性能测试工具 - Gatling

Gatling是一款基于Scala 开发的高性能服务器性能测试工具,它主要用于对服务器进行负载等测试,并分析和测量服务器的各种性能指标。Gatling主要用于测量基于HTTP的服务器,比如Web应用程序,...

匿名
2013/12/02
0
0
Shell: 测试网卡当前速率的脚本

一: 使用场景 工作中,有时为了分析系统的性能瓶颈, 需要测量程序运行期间网卡的当前速率, 看看瓶颈是不是在网络传输上. 本文提供一个测量网卡的当前速率的Shell脚本. 二: 脚本 使用方式: ./n...

cloud-coder
2014/04/24
0
2
DIY Ruby CPU 分析——Part I

【编者按】原文作者 Emil Soman,Rubyist,除此之外竟然同时也是艺术家,吉他手,Garden City RubyConf 组织者。本文是DIY Ruby CPU Profiling 的第一部分,由 OneAPM 工程师编译整理。 在 ...

OneAPM蓝海讯通
2015/09/25
21
0

没有更多内容

加载失败,请刷新页面

加载更多

http协议请求头的意义

GET /day31_Http_306/index.jsp HTTP/1.1: GET请求,请求服务器路径为/hello/index.jsp,协议为1.1 请求头 1.Host:localhost:请求的主机名为localhost2.User-Agent:Mozilla/5.0(Windows NT......

潇潇程序缘
35分钟前
6
0
Netty 简单服务器 (三)

经过对Netty的基础认识,设计模型的初步了解,来写个测试,试试手感 上篇也说到官方推荐我们使用主从线程池模型,那就选择这个模型进行操作 需要操作的步骤: 需要构建两个主从线程组 写一个服务器...

_大侠__
45分钟前
8
0
day02:管道符、shell及环境变量

1、管道符:"|" 用于将前一个指令的输出作为后一个指令的输入,且管道符后面跟的是命令(针对文档的操作):cat less head tail grep cut sort wc uniq tee tr split sed awk等) [root@localho...

芬野de博客
56分钟前
15
0
Kubernetes系列——Kubernetes 组件、对象(二)

一、Kubernetes 组件 介绍了Kubernetes集群所需的各种二进制组件。 Master 组件 Master组件提供集群的管理控制中心。Master组件可以在集群中任何节点上运行。但是为了简单起见,通常在一...

吴伟祥
今天
17
0
Flink-数据流编程模型

1、抽象等级 Flink提供了不同级别的抽象来开发流/批处理应用程序。 1) 低层级的抽象 最低层次的抽象仅仅提供有状态流。它通过Process函数嵌入到DataStream API中。它允许用户自由地处理来自一...

liwei2000
今天
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部