文档章节

go程序性能测量和分析

borey
 borey
发布于 2016/05/07 15:48
字数 626
阅读 156
收藏 5
点赞 2
评论 0
  • 性能测量

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

//斐波那契数
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
粉丝 26
博文 55
码字总数 31182
作品 0
深圳
程序员
> 读书笔记之Java性能优化

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

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

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

匿名
2013/12/02
0
0
DIY Ruby CPU 分析——Part I

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

OneAPM蓝海讯通
2015/09/25
21
0
Shell: 测试网卡当前速率的脚本

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

cloud-coder
2014/04/24
0
2
有的放矢,你应该在性能测试报告中使用的 10 个微观指标

摘要: 在这篇文章中,你将会了解到为什么常见的主要测试指标是不完美的,以及十个新的测量指标 —— 它们可能会改进你未来的性能测试报告。 性能测试是一项不可避免的任务,但问题是怎么保证...

开源中国
2017/11/22
0
0
Java性能调优工程的几点建议

2016年8月,由极客邦、InfoQ和听云联合主办APMCon 2016 中国应用性能管理大会上,Java性能调优专家Monica Beckwith进行了《Java性能调优必读守则》(原题目:Java Performance Engineer's S...

紫魅编程
2016/10/11
468
3
借助开源工具高效完成Java应用的运行分析

不止一次,我们都萌发过想对运行中程序的底层状况一探究竟的念头。产生这种需求的原因可能是运行缓慢的服务、Java虚拟机(JVM)崩溃、挂起、死锁、频繁的JVM暂停、突然或持续的高CPU使用率、...

五大三粗
2015/10/22
13
0
借助开源工具高效完成Java应用的运行分析

不止一次,我们都萌发过想对运行中程序的底层状况一探究竟的念头。产生这种需求的原因可能是运行缓慢的服务、Java虚拟机(JVM)崩溃、挂起、死锁、频繁的JVM暂停、突然或持续的高CPU使用率、...

五大三粗
2015/10/22
1
0
借助开源工具高效完成Java应用的运行分析

不止一次,我们都萌发过想对运行中程序的底层状况一探究竟的念头。产生这种需求的原因可能是运行缓慢的服务、Java虚拟机(JVM)崩溃、挂起、死锁、频繁的JVM暂停、突然或持续的高CPU使用率、...

五大三粗
2015/10/22
5
0
借助开源工具高效完成Java应用的运行分析

不止一次,我们都萌发过想对运行中程序的底层状况一探究竟的念头。产生这种需求的原因可能是运行缓慢的服务、Java虚拟机(JVM)崩溃、挂起、死锁、频繁的JVM暂停、突然或持续的高CPU使用率、...

五大三粗
2015/10/22
5
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

MyBatis源码解读之延迟加载

1. 目的 本文主要解读MyBatis 延迟加载实现 2. 延迟加载如何使用 Setting 参数配置 设置参数 描述 有效值 默认值 lazyLoadingEnabled 延迟加载的全局开关。当开启时,所有关联对象都会延迟加...

无忌
4分钟前
0
0
javascript 类变量的实现

代码如下: function echo(){ for(let i=0;i<arguments.length;i++) console.log(arguments[i]);}function extend(o, p){for (prop in p) {o[prop] = p[prop]}retur......

backbye
8分钟前
0
2
编程语言对比分析:Python与Java和JavaScript(图)

编程语言对比分析:Python与Java和JavaScript(图): 凭什么说“Python 太慢,Java 太笨拙,我讨厌 JavaScript”?[图] 编程语言生而为何? 我们人类从原始社会就是用语言表达自己,互相沟通...

原创小博客
17分钟前
0
0
Akka构建Reactive应用《one》

看到这Akka的官网,描述使用java或者scala构建响应式,并发和分布式应用更加简单,听着很高级的样子,下面的小字写着消息驱动,但是在quickstart里面又写容错事件驱动,就是这么钻牛角尖。 ...

woshixin
28分钟前
0
0
ffmpeg源码分析 (四)

io_open 承接上一篇,对于avformat_open_input的分析还差其中非常重要的一步,就是io_open,该函数用于打开FFmpeg的输入输出文件。 在init_input中有这么一句 if ((ret = s->io_open(s, &s-...

街角的小丑
30分钟前
0
0
String,StringBuffer ,StringBuilder的区别

不同点 一、基类不同 StringBuffer、StringBuilder 都继承自AbStractStringBuilder,String 直接继承自 Object 2、底层容器“不同” 虽然底层都是字符数组,但是String的是final修饰的不可变...

不开心的时候不要学习
45分钟前
0
0
nodejs 文件操作

写文件code // 加载文件模块var fs = require("fs");var content = 'Hello World, 你好世界!';//params 文件名,内容,编码,回调fs.writeFile('./hello.txt',content,'utf8',function (er......

yanhl
47分钟前
0
0
SpringBoot mybits 查询为0条数据 但是在Navicat 中可以查询到数据

1.页面请求: 数据库查询: 2018-07-16 17:56:25.054 DEBUG 17312 --- [nio-9010-exec-3] c.s.h.m.C.selectSelective : ==> Preparing: select id, card_number, customer_id, customer_nam......

kuchawyz
57分钟前
0
0
译:Self-Modifying cod 和cacheflush

date: 2014-11-26 09:53 翻译自: http://community.arm.com/groups/processors/blog/2010/02/17/caches-and-self-modifying-code Cache处在CPU核心与内存存储器之间,它给我们的感觉是,它具......

我叫半桶水
今天
0
0
Artificial Intelligence Yourself

TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统,其命名来源于本身的运行原理。Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算,TensorFlow为张量从流...

孟飞阳
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部