Skip to content

高质量编程-性能调优

芯笑

前言:

高质量的代码可以完成功能,但我们还需要考虑尽可能的提升性能,节省资源成本。本文结合Go语言展开。

性能优化建议

介绍:

Benchmark

性能的表现需要数据来说话,Go语言提供了支持基准性能测试的benchmark工具。

使用go test -bench=, -benchmem命名即可调用

// 一个例子
// from fib.go
func Fib(n int) int {
    if n < 2 {
        return n
    }
    return Fib(n - 1) + Fib(n - 2)
}

// from fib_test.go
func BenchmarkFib10(b *testing.B) {
    // run the Fib funciton b.N times
    for n := 0; n < b.N; n++ {
        Fib(10
    }
}

Slice:

尽可能在使用make()初始化的时候就提供容量信息,获得更好的性能。

当append之后的len<=cap,将会直接利用底层数组剩余的容量空间。但当len>cap时,则会分配一块更大的区域来容纳新的底层数组。因此,为了避免内存发生拷贝,最好预先设置cap。

究其原因:

另一个陷阱—大内存未释放:

有一种情况,原切片由大量元素构成,但是我们在原切片的基础上切片,虽然只使用了很小一段,但底层数组在内存中仍然占据了大量的空间,得不到释放。我们可以使用copy代替re-slice

//re-slice
func GetLastSlice(origin []int) []int {
    return origin[len(origin)-2:]
}
//copy
func GetLastCopy(origin []int) []int {
    result := make([]int,2)
    copy(result,origin[len(origin)-2:])
    return
}

可以使用go test -run=. -v来查看性能

Map预分配内存:

与slice一样,建议根据实际需求提前预估好需要的空间

原因:

字符串处理:

字符产拼接建议使用strings.Builder,使用+的拼接性能最差。分析:

// 例子
func StrBuilder(n int, str string) string {
    var builder strings.Builder
    for i := 0; i < n; i++ {
        builder.WriteString(str)
    }
    return builder.String()
}

空结构体:

空结构体是节省内存空间的一个手段。

// 一个例子
func EmptyStructMap(n int) {
    m := make(map[int]struct{})
    for i := 0; i < n; i++ {
        m[i] = struct{}{}
    }
}

func BoolMap(n int){
    m := make(map[int]bool)
    for i := 0; i < n; i++ {
        m[i] = false
    }
}

atomic包:

原子性:一个或多个操作在CPU的执行过程中不被中断的特性,称为原子性。这些操作对外表现成一个不可分割的整体,他们要么都执行,要么都不执行,外界不会看到他们只执行到一半的状态。

原子操作:进行过程中不能被中断的操作,原子操作由底层硬件支持,而锁则是由操作系统提供的API实现,若实现相同的功能,前者通常会更有效率

Go语言提供的原子操作都是非入侵式的,由标准库中sync/aotomic中的众多函数代表。

提供了 AddXXX、CompareAndSwapXXX、SwapXXX、LoadXXX、StoreXXX 等方法。

性能调优实战:

调优原则:

性能分析工具pprof:

炸弹程序:wolfogre/go-pprof-practice: go pprof practice. (github.com)

功能简介

实战排查

运行炸弹程序后打开浏览器访问http://localhost:6060/debug/pprof/即可查看数据。

排查实战:

详细文档:golang pprof 实战 | Wolfogre’s Blog(已经写的很好了,我又何必画蛇添足,实际操作一遍,自然就会了)

性能调优案例

业务服务优化:

业务服务一般指直接提供功能的程序。

基本概念:

流程:

通用的流程,也可以适用其它场景

永不满足,未完待续..

分享
上一篇
内存管理和性能优化
下一篇
高质量编程-编码规范