后端笔记 | 性能优化

154 阅读2分钟

性能优化:

Slice:

slice预分配内存

尽可能的在使用make(初始化切片的时候提供容量信息

eg:

image-20241108170847325

性能差异:

image-20241108170906742

why:

底层逻辑是slice预分配一部分内存

如果内存不够的情况下,系统会对切片进行一次扩容

这个扩容的过程会比较耗费时间,所以如果指定大小的话就会好分配内存

image-20241108171107117

大内存未释放:

在已有切片基础上创建切片。不会创建新的底层数组

原切片较大,代码在原切片基础上新建小切片,原底层数组

底层数组在内存中有引用,得不到释放,

可以用copy代替re-slice

image-20241108171529745

map同理,预分配内存的话性能提升会很大的

不断向map中添加元素的操作会触发map的扩容

提前分配好空间可以减少内存拷贝的rehash的小号

所以说,在有条件的情况下

建议根据诗句需求提前预估好需要的空间

字符串:

使用+的性能最差,strings.Builder,bytes.Budffer相近,还是strings.Buffer更快

why:

因为在go语言中字符串是不可变类型,使用的内存大小是不变的

每次使用+都会重新分配内存

strings.Builder,bytes.Budffer底层都是[]byte数组

有他们自身的内存扩容策略,不需要每次拼接都重新分配内存

bytes.Buffer转化为字符串是重新申请了一块空间

string.Bulider直接将底层的[]byte转化成了字符串类型返回

空结构体:

孔结构体struct{}实例不占据任何的内存

可以位错各种场景下的占位符使用

节省资源,孔结构体不省油很强的寓意,这里不需要任何值,仅作为占位符

image-20241108173848016

image-20241108180118904

性能调优原则

1.要依靠数据而不是猜测

实际吧

2.要定位最大瓶颈而不是细枝末节

3.不要过早优化

因为在后续的代码编写中可能会替换掉这些所以要再最后再进行优化

4.不要过度优化

过度优化可能会出现一些功能实现不了,所以要掌握一个度

工具;

pprof