performance - ¿Qué tan caro es[] byte(cadena)?
go type-conversion (2)
Vamos a convertir la string
a []byte
:
func toBytes(s string) []byte {
return []byte(s) // What happens here?
}
¿Qué tan costosa es esta operación de fundición? ¿Se realiza copia? Por lo que veo en la especificación de Go: las cadenas se comportan como segmentos de bytes pero son inmutables , esto debería implicar al menos una copia para asegurarse de que las operaciones de segmentos subsiguientes no modifiquen nuestra cadena de caracteres. ¿Qué pasa con la conversación inversa? ¿ []byte <-> string
conversación de []byte <-> string
implica codificación / decodificación, como utf8 <-> runas?
El []byte(s)
no es una conversion sino una conversion . Algunas conversiones son lo mismo que una conversión, como uint(myIntvar)
, que simplemente reinterpreta los bits en su lugar . Desafortunadamente, este no es el caso de la conversión de segmento de cadena a byte. Los segmentos de bytes son mutables, las cadenas (los valores de cadena para ser precisos) no lo son. El resultado es una copia necesaria (mem alloc + content transfer) de la cadena que se está realizando. Entonces sí, puede ser costoso en algunos escenarios.
EDITAR: No se realiza ninguna transformación de codificación. Los bytes de la cadena (origen) se copian en los bytes de la porción (destino) tal como son.
La conversión copia los bytes, pero también asigna espacio para el byte [] en el montón. En los casos en los que convierta cadenas a [] byte repetidamente, puede ahorrar tiempo de administración de memoria al reutilizar el byte [] y usar el comando de copia. (Consulte http://golang.org/ref/spec#Appending_and_copying_slices y el caso especial sobre el uso de una cadena como fuente).
En ambos casos de la conversión y el comando de copia, la copia en sí misma es una copia de un byte directo que debe ejecutarse muy rápidamente. Yo esperaría que el compilador genere algún tipo de instrucción de movimiento de repetición que la CPU ejecuta de manera eficiente.
La conversión inversa, que hace que una cadena salga de un segmento de bytes, definitivamente implica asignar la cadena en el montón. La propiedad de la inmutabilidad obliga a esto. A veces puede optimizar haciendo el mayor trabajo posible con el byte [] y luego creando una cadena al final. El tipo bytes.Buffer es a menudo útil.
Persiguiendo la pista falsa ahora, la codificación y el UTF-8 no son problemas. Las cadenas y el byte [] pueden contener datos arbitrarios. La copia no mira los datos, solo los copia. Elija las palabras con cuidado cuando diga cosas como que las cadenas tienen la intención de contener UTF-8 o que esto se recomienda . Es más preciso simplemente observar que algunas características del lenguaje, como la cláusula de rango de una instrucción for, interpretan las cadenas como UTF-8. Solo aprenda qué interpreta las cadenas como UTF-8 y qué no. ¿Tiene un non-UTF-8 en una cadena y necesita extenderse sobre él por byte? No hay problema, simplemente no use la cláusula de rango.
s := "string"
for i := 0; i < len(s); i++ {
b := s[i]
// work with b
}
Esto es idiomático Go. No se desanima y no viola ninguna intención. Simplemente itera sobre la cadena por byte, que a veces es justo lo que quieres hacer.