【Go基础学习】编码规范及性能调优

104 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第25天,点击查看活动详情 这也是第30篇文章

参考资料

字节内部课后端模块

错误和异常处理

简单错误 error

  • 用errors.New()表示简单错误
  • 用fmt.Errorf()格式化错误

panic

不建议在业务代码中使用panic,因为调用函数不包含recover时会造成程序崩溃。

使用场景:当程序启动阶段发生不可逆转的错误时, 可以在init或main函数中使用panic

recover

只能在当前协程的被defer函数中生效

  • 嵌套无法生效
  • defer是先进后出(栈)

性能优化建议

slice

  • 尽可能在用make()初始化切片时提供容量信息

原因:创建一个新的切片会复用原来切片的底层数组

以切片的append为例,append时有两种场景:

当append之后的长度小于等于cap,将会直接利用原底层数组剩余的空间;

当append后的长度大于cap时,则会分配一块更大的区域来容纳新的底层数组。

因此先设置cap的值能够避免额外的内存分配,获得更好的性能

  • 使用copy代替re-slice

原因:考虑如下情景:

原切片由大量的元素构成,但是是我们在原切片的基础上切片,虽然只使用了很小一 段,但底层数组在内存中仍然占据了大量空间,得不到释放。

通过copy,指向新的底层数组,当原始数组不再被引用后,内存会被垃圾回收。

Map

Map也被推荐使用预分配内存的形式(如果可以的话),以减少内存拷贝和rehash的消耗

字符串处理

和Java类似,builder buffer 直接+都可以,但是性能优劣也是按这个顺序。优先使用builder(更快)

原因:看一下builder和buffer的代码: image.png

image.png buffer返回时是新申请一块空间;而builder是直接进行类型转换

空结构体

空结构体不占据任何存储空间,可作为占位符。

Set的实现

Go语言中并没有标准的Set实现,可以用Map来自己实现一个Set,只用其键,不用其值

关于原子性的应用

以下内容涉及操作系统的理论知识:

image.png

性能优化原则

  • 用数据和事实说话,不要主观臆断
  • 抓住主要矛盾的主要方面
  • 不要过早、过度优化

关于性能调优工具pprof,之前参考大佬们的青训营笔记之后自己也在示例项目中体验了用法(忘了有没有整理成文章了),之后有需要再更这一块的内容。