BacCM
@BacCM
C++ почти с рождения

Как в GO преобразовать тип массива/слайса без копирования?

Есть задача записать в бинарный файл набор чисел типа float.

Вроде как, самый правильный способ с контролем порядка байт и прочего это такой:
d := make([]float32, vectorDataLen)
for x := 0; x < len(d); x++ {
	d[x] = float32(x)
}
var bin_buf bytes.Buffer
binary.Write(&bin_buf, binary.LittleEndian, d)
n, err := dat_file.Write(bin_buf.Bytes())


Но в этом случае данные копируются лишний раз и память перевыделяется, что тоже, как кажется, неоптимально.

Попробовал поиграться с встроенным пакетом unsafe:

const SZ = 1000
func test_unsafePointer() {

	d := make([]int, SZ)

	for x := 0; x < len(d); x++ {
		d[x] = x
	}

	p1 := (unsafe.Pointer(&d[0]))

	b := *(*[SZ * unsafe.Sizeof(d[0])]byte)(p1)
	p2 := (unsafe.Pointer(&b[0]))

	s := b[:]
	p3 := (unsafe.Pointer(&s[0]))

	println("len(d)= ", len(d))
	println("len(b)= ", len(b))
	println("len(s)= ", len(s))
	s = append(s, s...)
	p4 := (unsafe.Pointer(&s[0]))
	println("len(s+)= ", len(s))

	println("pointers = ", p1, " ", p2, " ", p3, " ", p4)
}




len(d)= 1000
len(b)= 8000
len(s)= 8000
len(s+)= 16000
pointers = 0xc00006c030 0xc00006a0f0 0xc00006a0f0 0xc000072000



Получатся, что массив "переносится" в слайс без копирования, и с сохранением функционала последнего (p2==p3), что логично при дополнении слайса память под него перевыделяется: p4 уже не равен p3
А вот как бороться с перевыделением d->b ? p1 != p2
  • Вопрос задан
  • 654 просмотра
Пригласить эксперта
Ответы на вопрос 1
DexterHD
@DexterHD
Software Engineer, Teamlead, CTO
А если сразу писать в файл? binary.Write ведь принимает интерфейс io.Writer. Значит открытый на запись файл нам подходит.

import (
	"encoding/binary"
	"os"
)

func main() {

	dat_file, _ := os.Create("test.txt")
	defer dat_file.Close()

	vectorDataLen := 1000
	d := make([]float32, vectorDataLen)
	for x := 0; x < len(d); x++ {
		d[x] = float32(x)
	}

	binary.Write(dat_file, binary.LittleEndian, d)
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы