Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

Gray-Ice

个人博客兼个人网站

本篇内容基于: Go 语言高性能编程

注意: 本文内容不全,不建议观看!

注意: 本文仅指出结果,原理和测试过程请在原文(第一段的超链接)中检索。本文中的副标题仅对应原文中的标题,不含任何其他意义。

字符串拼接性能及原理

1
使用+和fmt.Sprintf的效率是最低的。strings.Builder, bytes.Buffer和[]byte的性能差距不大,消耗的内存也十分接近。综合易用性和性能,一般推荐使用 strings.Builder 来拼接字符串。

切片性能及陷阱

1
2
3
4
5
6
长度不同的两个数组是不可以相互赋值的,因为这 2 个数组属于不同的类型。
在 C 语言中,数组变量是指向第一个元素的指针,但是 Go 语言中并不是。Go 语言中,数组变量属于值类型(value type),因此当一个数组变量被赋值或者传递时,实际上会复制整个数组。为了避免复制数组,一般会传递指向数组的指针。

切片操作并不复制切片指向的元素,创建一个新的切片会复用原来切片的底层数组,因此切片操作是非常高效的。
在已有切片的基础上进行切片,不会创建新的底层数组。因为原来的底层数组没有发生变化,内存会一直占用,直到没有变量引用该数组。因此很可能出现这么一种情况,原切片由大量的元素构成,但是我们在原切片的基础上切片,虽然只使用了很小一段,但底层数组在内存中仍然占据了大量空间,得不到释放。比较推荐的做法,使用 copy 替代 re-slice。

for 和 range 的性能比较

1
range 在迭代过程中返回的是迭代值的拷贝,如果每次迭代的元素的内存占用很低,那么 for 和 range 的性能几乎是一样,例如 []int。但是如果迭代的元素内存占用较高,例如一个包含很多属性的 struct 结构体,那么 for 的性能将显著地高于 range,有时候甚至会有上千倍的性能差异。对于这种场景,建议使用 for,如果使用 range,建议只迭代下标,通过下标访问迭代值,这种使用方式和 for 就没有区别了。如果想使用 range 同时迭代下标和值,则需要将切片/数组的元素改为指针,才能不影响性能。

Go 空结构体 struct{} 的使用

1
2
3
4
5
空结构体 struct{} 实例不占据任何的内存空间。
因为空结构体不占据内存空间,因此被广泛作为各种场景下的占位符使用。一是节省资源,二是空结构体本身就具备很强的语义,即这里不需要任何值,仅作为占位符。
因此呢,将 map 作为集合(Set)使用时,可以将值类型定义为空结构体,仅作为占位符使用即可。
有时候使用 channel 不需要发送任何的数据,只用来通知子协程(goroutine)执行任务,或只用来控制协程并发度。这种情况下,使用空结构体作为占位符就非常合适了。
无论是 int 还是 bool 都会浪费额外的内存,因此呢,这种情况下,声明为空结构体是最合适的。

评论



愿火焰指引你