文档章节

go程序性能测量和分析

borey
 borey
发布于 2016/05/07 15:48
字数 626
阅读 166
收藏 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
粉丝 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
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
Java性能调优工程的几点建议

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

紫魅编程
2016/10/11
468
3

没有更多内容

加载失败,请刷新页面

加载更多

Mybatis中jdbcType和javaType的对应关系 

Mybatis中jdbcType和javaType的对应关系 1 JDBC Type Java Type 2 CHAR String 3 VARCHAR String 4 LONGVARCHAR String 5 NUMERIC java.math.BigDecimal 6 DECIMAL java.math.BigDecimal 7 ......

DemonsI
12分钟前
1
0
Python中字符串和datetime

遇到的问题: 今天在写一个爬虫时,需要将今天的数据和昨天、一周前的数据做比较。所以就需要一个方法可以方便的计算出指定日期的前几天的日期。比如10月3号,则一周前的日期是9月26号。 问题...

akane_oimo
14分钟前
1
0
企业级 SpringBoot 教程 (四)SpringBoot 整合JPA

JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。 JPA 的目标之一是制定一个可以由很多供应商实现的API,并且开发...

itcloud
15分钟前
1
0
白话SpringCloud | 第六章:Hystrix监控面板及数据聚合(Turbine)

前言 前面一章,我们讲解了如何整合Hystrix。而在实际情况下,使用了Hystrix的同时,还会对其进行实时的数据监控,反馈各类指标数据。今天我们就将讲解下Hystrix Dashboard和Turbine.其中Hys...

oKong
26分钟前
1
0
Java JDK 11:现在可以使用所有新功能

删除了CORBA,Java EE和JavaFX支持,但添加了十几个主要新功能 目录 哪里可以下载JDK 11 Java 11 JDK中的新功能 从Java JDK 11中删除了什么 Java Development Kit(JDK)11现已普遍可用,可供...

GuoMengyue
27分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部