性能优化浅析 | 青训营笔记

63 阅读3分钟

这是我参与[第五届青训营]伴学笔记创作活动的第5天。

概述

性能优化的前提就是正确可靠、简洁清晰等质量因素

性能优化是综合评估,要切合实际问题进行结局优化问题

但是面向实际应用层面上解决的是良好的用户体验和有限的资源之间的矛盾

benchmark

简介:Go的标准库内置的testing框架提供了基准测试(benchmark)功能,可以用来验证本地方法在串行或者并行执行时的基准表现,帮助开发者了解代码的真实性能情况。

benchmark是用来对已有方法做测试的,因此一开始要把被测试的方法准备好,然后像单元测试那样编写benchmark测试代码,最后用go test做基准测试

在这引入一下最基本的基准测试,最基本的基准测试是从两个维度去检验项目的性能

  • 指定时间,检查方法运行的次数
  • 指定次数,检查方法运行的耗时

当然,在某些方面对于项目有并发需求,如果被测试的方法在真实环境中存在并发调用,那么在基准测试中也应该通过并行测试来了解其基本性能(例如锁造成的阻塞)

在强调速度的同时,内存分配也是一个很重要的指标,Go语言几种字符串的拼接方式比较一文中做个比较,在使用strings包的builder类型去做字符串拼接的时候,是否合理的预分配内存,测试的结果是不同的,如果我们能合理的预分配内存,那么性能也会有较大的提升。

Slice

简介:Go的 Slice(切片)类型提供了一种方便有效的方法来处理类型化数据序列。 slice类似于其他语言中的数组,但具有一些不寻常的属性。数组有它们的位置,但是它们有点不灵活,所以你不会在Go代码中经常看到它们。 然而,Slice无处不在。 它们以阵列为基础,提供强大的功能和便利性。 与数组类型不同,Slice类型没有指定的长度。

切片是数组段的描述符。 它由指向数组的指针,段的长度及其容量(段的最大长度)组成。长度是切片引用的元素数。 容量是底层数组中元素的数量(从切片指针引用的元素开始)。切片不会复制切片的数据。 它创建一个指向原始数组的新切片值。 这使切片操作与操作数组索引一样高效。切片不能超出其容量。 尝试这样做会导致运行时出现混乱,就像在切片或数组的边界之外进行索引一样。 类似地,切片不能在零以下重新切片以访问数组中的早期元素。

需要注意的是,重新切分切片不会复制底层数组。 完整数组将保留在内存中,直到不再引用它为止。 偶尔这会导致程序在只需要一小部分数据时将所有数据保存在内存中。

Map

map是Go语言中基础的数据结构,在日常的使用中经常被用到。总体来说golang的map是hashmap,是使用数组+链表的形式实现的,使用拉链法消除hash冲突。golang的map由两种重要的结构,hmap和bmap,主要就是hmap中包含一个指向bmap数组的指针,key经过hash函数之后得到一个数,这个数低位用于选择bmap(当作bmap数组指针的下表),高位用于放在bmap的uint8数组中,用于快速试错。然后一个bmap可以指向下一个bmap(拉链)。