【发布时间】:2019-08-16 08:42:44
【问题描述】:
我想知道是否可以将sync.Pool 与数组或切片一起使用?例如,sync.Pool 可以在每秒处理数万个请求时加快以下速度吗?这个例子只是为了更好地理解 Go。
// Handler that uses GenerateArray
func ok(w http.ResponseWriter, r *http.Request) {
var res [100000]uint64
fibonacci.GenerateArray(&res)
fmt.Fprintf(w, "OK")
}
func GenerateArray(data *[100000]uint64) {
var start uint16 = 1000
var counter uint32
for start >= 1 {
var num = 90
var n1, n2, temp uint64 = 0, 1, 0
for num >= 1 {
temp = n2
n1, n2 = temp, n1+n2
data[counter] = n2
counter++
num--
}
start--
}
}
编辑:这是 Icza 建议的切片版本。希望我在学习时做对了。
res := make([]uint64, 100000)
fibonacci.GenerateSlice(res)
// PopulateSlice does this...
func PopulateSlice(data []uint64) {
var start uint16 = 1000
var counter uint32
for start >= 1 {
var num = 90
var n1, n2, temp uint64 = 0, 1, 0
for num >= 1 {
temp = n2
n1, n2 = temp, n1+n2
data[counter] = n2
counter++
num--
}
start--
}
}
退货。
func GenerateSlice() []uint64 {
data := make([]uint64, 0, 100000)
var start uint16 = 1000
var counter uint32
for start >= 1 {
var num = 90
var n1, n2, temp uint64 = 0, 1, 0
for num >= 1 {
temp = n2
n1, n2 = temp, n1+n2
// data[counter] = n2
data = append(data, n2)
counter++
num--
}
start--
}
return data
}
【问题讨论】:
-
你会看到一个很常见的情况是在 go 中不鼓励使用 arrays,除了几个 very 特定的情况,最好使用切片(最好有明确的上限)。将指针传递给切片/数组也有点奇怪。您的函数称为
GenerateArray,但实际上它是填充 一个已经创建的数组。只需创建 && 返回 -
@EliasVanOotegem 我忘了重命名它。最初它生成一个数组并返回它。我从切片开始,但性能非常糟糕。通过指向数组的指针,我能够将性能提高一倍以上。
-
您只是使用了切片文字,还是指定了上限/长度?
-
data := make([]uint64, 100000)cap/len 带索引和data := make([]uint64, 0, 100000)带附加 -
第一个是指定长度,用 C 术语来说,相当于
uint64 *data = calloc(100000, sizeof *data);(在堆上分配,并将内存初始化为零。第二个分配一块内存(乐观地),每个append 将初始化一个给定值的新偏移量。这只是粗略的笔划,但本质上就是这样。使用数组在堆栈上分配(如果可能的话),因此开销会少一些,但你正在传递一个指针,它仍然引入了一个间接级别。顺便说一句,在最后一个 sn-p 中,countervar 是多余的