www.state-it.info

Gran base de respuestas a las preguntas de los desarrolladores
Header decor

Como en el GO convertir el tipo de matriz/ "slice" sin copia de seguridad?

BacCM 2018-11-01 18:07:19

Tienen la tarea de escribir en un archivo binario de un conjunto de números de tipo float.

Algo así como, más de la forma correcta con el control de la orden de bytes y otras cosas es un:

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())


Pero en este caso, los datos se copian una vez más y la memoria перевыделяется, que también, como parece, no sea óptima.

Intenté jugar con un paquete de 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
punteros impares = 0xc00006c030 0xc00006a0f0 0xc00006a0f0 0xc000072000



Verán que la matriz "tolerado" en la "slice" sin copia de seguridad, y con la preservación de la funcionalidad de la última (p2==p3), es lógico que cuando el suplemento de "slice" memoria por debajo de él перевыделяется: p4 ya no es igual p3
Y así es como luchar con перевыделением d->y b ? p1 != p2

BacCM 2018-11-01 18:52:53

rustler2000unidad de método. Si de repente, algo en la organización de "slices" en рантайме Go se sustituye en una de las futuras versiones...
Aunque es bastante trabajo...


rustler2000 2018-11-01 19:28:14

BacCM, pues la unsafe mismo. Bueno, y las pruebas no es difícil de escribir


Total answers: 1

DexterHD 2018-11-01 20:18:01

Y si la vez de escribir en el archivo? binary.Write ya que adopta la interfaz io.Writer. Significa una piscina al aire en la entrada de archivo adecuada para nosotros.

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)
}

rustler2000 2018-11-01 22:03:30

Sólo él en un "slice" copia de элементно a través de рефлект :E


BacCM 2018-11-02 00:14:46

se Escribe un poco más ordenado que mi opción, pero el significado es casi el mismo.


rustler2000 2018-11-02 09:55:43

BacCM,

package main

// #include <unistd.h>
import "C"
import (
	"log"
	"os"
	"unsafe"
)

func main() {
	f, err := os.Create("file.bin")
	defer f.Close()
	if err != nil {
		log.Fatal(err)
	}
	fd := f.Fd()

	s := []float32{1.1, 1.2, 1.3, 1.4, 2.2, 4.5}

	p := unsafe.Pointer(&s[0])
	l := C.ulong(len(s) * int(unsafe.Sizeof(s[0])))
	n := C.write(C.int(fd), p, l)
	
	log.Printf("writen %v\n", n)
}


BacCM 2018-11-02 10:53:27

rustler2000, sobre estos gastos también pensaba. Me gusta incluso más que la de todo tipo de manipulación de la unsafe + manual ковыряние de "slices". Sólo suponía hacer una función externa de donde сишную llamar para no tirar en el código principal, algo ненативное.


rustler2000 2018-11-02 12:29:45

BacCM, sólo es cgo requiere :( esdecir, CGO_ENABLED=0 go build ya no funciona


DexterHD 2018-11-02 12:53:55

BacCM, Surge una pregunta interesante, aunque no muy en el tema. Y esto es real en el contexto de su tarea tan importante. Es decir, es el verdadero desafío de la vida, que realmente requiere tan fuerte a la optimización? O es simplemente el interés, es decir, la optimización de la que tiene realmente mucho sentido? Porque unsafe en Go generalmente reconocido como el mal tono, y los desarrolladores de la lengua en cada paso dicen literalmente: "- No utilice esto es todo, hasta que antes de que usted realmente no fue un problema. Porque el uso de todos estos mecanismos de usted, en principio, отсекаете todas las ventajas que da el Go."


BacCM 2018-11-02 15:32:53

DexterHD, En este caso puramente académico de la pregunta. Era necesario echar un par de utilidades que hice en "estado puro" Go y tranquilo para el uso de los frutos de su trabajo. Go eligió simplemente para practicar, al mismo tiempo, mostrar en la práctica el trabajo con archivos.

Pero no hace mucho tiempo, era necesario el procesamiento real de grandes volúmenes de datos (para pc estándar). La utilidad escritas en C лопатили su reloj, aunque esto ha sido una pequeña parte de lo que es el cliente para procesar completamente, es probable que se trataba de decenas de horas o incluso días.


Preguntas relacionadas:

Footer decor

© www.state-it.info | Base of answers to questions for developers and programmers.