性能优化建议 | 青训营笔记

87 阅读3分钟

这是我参与「第五届青训营」笔记创作活动的第七天。

一:本堂课的重点内容

性能优化建议

二:详细知识点如下

1、benchmark

go语言提供了支持基准性能测试的工具:benchmark

1)作用

可以用来测试某个函数或者任何代码的执行时间

2)用法
import (
    "fmt"
    "testing"
)
func BenchmarkSprint(b *testing.B) {
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        fmt.Sprint(i)
    }
}

运行:go test -bench=. -run=none 命令得到以下结果:

image.png 运行benchmark基准测试也要用到 go test 命令,不过我们后面需要加上-bench=参数,接受一个表达式作为参数,匹配基准测试的函数,"."一个点表示运行所有的基准测试。 因为默认情况下 go test 会运行单元测试,为了防止单元测试的输出影响我们查看基准测试的结果,可以使用-run=匹配一个从来没有的单元测试方法,过滤掉单元测试的输出。

2、slice

1)slice预分配内存

image.png image.png

2)大内存未释放

image.png

3、Map

map预分配内存

建议:

image.png

4、字符串处理

1)使用strings.Builder

image.png 原因:

image.png

image.png

5、空结构体

使用空结构体节省内存,不占存储空间,

image.png

6、atomic

1)atomic介绍

sync/atomic包提供了原子操作的能力,直接有底层CPU硬件支持,因而一般要比基于操作系统API的锁方式效率高些;这些功能需要非常小心才能正确使用。 除特殊的底层应用程序外,同步更适合使用channel或sync包的功能。

image.png image.png

2)扩展知识

对于原子操作, 还有几条具体的使用建议:

不要把内部使用的原子值暴露给外界。比如, 声明一个全局的原子变量并不是一个正确的做法, 这个变量的访问权限最起码也应该是包级私有的。

如果不得不让包外, 或模块外的代码使用你的原子值, 那么可以声明一个包级私有的原子变量, 然后再通过一个或多个公开的函数, 让外界间接地使用到它。注意, 这种情况下不要把原子值传递到外界, 不论是传递原子值本身还是它的指针值。

如果通过某个函数可以向内部的原子值存储值的话, 那么就应该在这个函数中先判断被存储值类型的合法性。若不合法, 则应该直接返回对应的错误值, 从而避免 panic 的发生。

如果可能的话, 我们可以把原子值封装到一个数据类型中, 比如一个结构体类型。这样, 我们既可以通过该类型的方法更加安全地存储值, 又可以在该类型中包含可存储值的合法类型信息.

三、课后个人总结

普通代码不能一味追求程序的性能,应该一步一个脚印,循序渐进,越高级的性能优化手段越容易出现问题,应该在代码质量合格的前提下提高性能。 无论是内存、CPU还是前端页面,都有很多的profile工具,解决了一两个最大的性能问题,往往就可以突破瓶颈。要先通过这些profile工具找到真正的问题所在。否则很有可能做无用功。2-8法则在很多情况下都是成立的。

四、引用参考

events.jianshu.io/p/a318318c2… blog.csdn.net/zhghost/art… blog.csdn.net/wan212000/a…