[程序调优|青训营笔记]

33 阅读2分钟

调优对象

一般可以对以下的情况进行调优

  1. Slice的使用
  2. Map的使用
  3. 字符串处理
  4. 空结构体
  5. atomic包的调用
Slice的优化

在创建切片的时候,需要尽量在make()初始化的时候提供容量,同样的代码预先指定容量和不指定容量的make运行区别如下。

image-20230117225403294

可以明显的感受到预先指定容量的make运行速度和消耗内存都优于另一种。

所以在平常使用slice的时候尽量的去在创建时指定容量大小,会让你写出更好的代码嘞。但是这是为啥呢?可以看看slice的底层实现原理。

先给出slice的源码

 type slice struct {
     array unsafe.Pointer
     len int
     cap int
 }

从上面的代码可以看出来切片包含以下内容

  • 指向底层数组的指针
  • 切片的长度
  • 切片的容量

他并没有任何储存其他值的变量,所以可以看出他不会复制底层数组的元素,并且若在原有的切片的基础上创建一个新的切片,但是其仍然是指向原来的底层数组。

若程序在初始化时能预先知道切片的cap值可以避免额外分配其内存空间,因而获得更好的性能。

Map的优化

Map在平成也是经常使用的。不只是slice初始化时预设定好内存可以优化性能Map预先设定好容量cap同样也能优化性能。首先创建一个map并增加同等数量的键值对,性能消耗如下图。

image-20230117231544342

不出意外预先设定好容量的程序的性能更加的优异

原因

在golang中map是通过hash表(数组+hash桶)来实现的,而在给map增加键值对的时候会触发map的自动扩容的机制,在map自动扩容的过程中程序会把键(Key)进行哈希处理使其转换成一哈希值并存储在数组中并将值拷贝到桶中。若不限预定好容量程序并不能提前分配好空间,这就导致每进行一次自动扩容分配一次空间,这样会造成大量的性能浪费,所以建议预先设置好容量。