编程规范和性能调优 | 青训营笔记

42 阅读2分钟

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

今天的掘金课程主要是两部分,一个是go语言的大概编程规范,一个是性能测试工具的使用和性能调优如何进行。

go语言编程规范部分与go语言官方手册中effective go的部分基本一致。在注释方面go语言不像其他语言的doc gen方案有大量的格式要书写,而是遵循着解释功能的一段文字这一概念,给出函数的功能,期望输入与输出。有一点要注意的是一般不要在接口的实现加注释,因为接口本身的函数功能应该有注释。在条件分支方面,要尽量减少嵌套,正常逻辑不要放在分支里进行。在错误与异常处理方面,可以通过error.Iserror.Aserror.Unwrap进行异常链的保存和读取,通过在使用fmt.Errorf时使用%w代替%v输出之前的错误,再在检查错误时通过error.Is便可读出之前的错误并通过error.As将这个原始错误提取出来。在处理panic时可以使用recover方法,其只在defer调用时才生效。

在做go程序的性能测试时,最原始的方法就是直接使用在go test框架中的Benchmark工具,通过书写以Benchmark开头的函数,进行性能测试,并找出可以优化的点。这里,老师给出了几个测试示例和相应的优化建议。首先就是通过在已知需要内存空间大概大小的情况下,对容器进行空间的预分配,减少程序执行时内存重分配的次数。根据这个假设又可以推得,在进行字符串拼接时,使用标准库中给出的strings.Builder先调用Grow方法预分配空间,再拼接字符串可以减少大量的内存分配和复制次数。strings.Builder的这种优化特性也导致它并不是那么灵活,并不像Java中的StringBuilder那样支持多种操作,只能用于向尾部添加字符。同时由于自动内存管理和切片对于底层数组的引用特性,容易因为切片的传播导致一些数组空间难以释放,这时在保证正确性的前提下可以分配新的底层数组给切片使用,减少内存空间的浪费,很像Java在JDK中对String类型的改动。同时在希望使用map类型来当做set使用时,通过空结构体struct{}不占用内存空间的特性,可以有效减少内存占用。