package main
import (
"fmt"
"unsafe"
"runtime"
)
func getPoi() unsafe.Pointer {
var a = []int{1, 2, 3}
return unsafe.Pointer(&a[0])
}
func main() {
p := getPoi()
runtime.GC()
fmt.Println("Hello, playground %v\n", *(*int)(unsafe.Pointer(uintptr(p)+8)))
}
https://play.golang.org/p/-OQl7KeL9a
Просто исследующие способности небезопасных указателей, пытаясь свести к минимуму накладных расходов памяти структуры среза (12 байт)
Интересно, если этому пример правильно или нет. И если нет, то что будет не так точно после таких действий. если это неверно, почему значение все еще доступно даже после явного вызова GC? Есть ли какой-либо aproach для достижения минимальных накладных расходов при хранении, таких как «кусочек срезов», как это было бы в C (просто массив указателей на выделенные массивы, когда накладные расходы для каждой строки - sizeof (int *)).
Возможно, вам лучше сократить потребление памяти с помощью int32 или даже int16, чем сэкономить 2 * 8 байт, заменив заголовок среза небезопасным.Pointer. Для случая среза кусочка среза: сделайте один срез и сделайте сам расчет индекса (см., Например, изображение пакета). – Volker
Также имейте в виду, что int составляет 4 байта на 32-битных системах и 8 байтах на 64-битной, поэтому, если вы собираетесь использовать указатели, убедитесь, что вы используете размер int. Кроме того, если производительность срезов действительно важна, используйте Go from git (или подождите 1.7), произошли значительные улучшения производительности. – OneOfOne
yep, все замечания разумны, но в некоторых случаях они неприемлемы. например, если у меня есть динамическая таблица записей, было бы неудобно работать с твердым срезом с использованием индексных вычислений, удаление строк из сплошного среза было бы очень тяжелым. в этом случае, я думаю, кусочек ломтиков является наиболее предпочтительным подходом. – Exel