[英]Get pointers for values in the slice
有沒有辦法獲得指向切片中實際值的指針? 我在地圖上有一棵報價樹:
map[uint64]map[uint16][]offer
為了通過 id(從 1 到 n)快速訪問,我需要一片指針:
[]*offer
實際報價位於第一棵樹中,切片中應該是指向實際報價的指針。
我無法遍歷樹並收集實際值的指針,因為這個切片的range
給了我一個副本,但我總共有超過數十億個這樣的結構,副本會導致我的內存浪費:一個結構導致 40 字節到 100+ GB 以及未來更多。 我還需要將樹中的值片段存儲為連續的,以便實際查找要約。
可能有什么方法可以使用unsafe
或reflect
包來獲取這些指針?
指針索引僅構建一次,並且兩個結構都是不可變的,僅用於查找報價。
更新:我完全錯了。 獲取切片中元素的指針沒有問題。 我的代碼是:
var offers []offer // actually there was about 50gb of offers
for i := range offers {
currentOffer := offers[i]
s.Relations[currentOffer.Id] = ¤tOffer
}
在此片段之后,應用程序消耗的 ram 總量變為 100+gb。 我立即認為從值的切片中獲取元素會給我一個該值的副本,但這是錯誤的。 我只是自己將原始值復制到currentOffer
變量中。 一個小錯誤帶走了 50GB 的內存。
實際上,此代碼段按預期工作正常:
for i := range offers {
s.Relations[offers[i].Id] = &offers[i]
}
經過一番調查,我得出了以下代碼:
package main
import (
"fmt"
"reflect"
"unsafe"
)
type offer struct {
id uint64
}
func main() {
sl := []offer{{1}, {id: 2}}
size := unsafe.Sizeof(offer{})
header := (*reflect.SliceHeader)(unsafe.Pointer(&sl))
for i := 0; i < len(sl); i++ {
offset := uintptr(i) * size
ptr := header.Data + offset
o := (*offer)(unsafe.Pointer(ptr))
o.id = 5
fmt.Println(o)
}
for _, o := range sl {
fmt.Println(o.id)
}
}
游樂場: https : //play.golang.org/p/OM3i84cKAB_7
輸出:
&{5}
&{5}
5
5
這段代碼說明了對切片中實際數據的訪問,而不是復制的數據。
更新:通過不安全指針獲取指針與按索引從切片中獲取常規指針具有相同的效果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.