¿Qué método es el mejor (más idomático) para probar cadenas no vacías (en Go)?
if len(mystring) > 0 { }
O:
if mystring != "" { }
¿O algo mas?
Ambos estilos se usan dentro de las bibliotecas estándar de Go.
if len(s) > 0 { ... }
se puede encontrar en el strconv
paquete: http://golang.org/src/pkg/strconv/atoi.go
if s != "" { ... }
se puede encontrar en el encoding/json
paquete: http://golang.org/src/pkg/encoding/json/encode.go
Ambos son idiomáticos y son lo suficientemente claros. Es más una cuestión de gusto personal y de claridad.
Russ Cox escribe en un hilo de nueces de golang :
El que aclara el código.
Si estoy a punto de ver el elemento x, normalmente escribo
len (s)> x, incluso para x == 0, pero si me importa
"¿es esta cadena específica" tiendo a escribir s == "".Es razonable suponer que un compilador maduro compilará
len (s) == 0 y s == "" en el mismo código eficiente.
...Haz el código claro.
Como se señaló en la respuesta de Timmmm , el compilador Go genera código idéntico en ambos casos.
if mystring != "" { }
es la mejor, preferida e idiomática HOY. La razón por la que la biblioteca estándar contiene lo contrario es porque fue escrita antes de 2010 cuando lalen(mystring) == 0
optimización tenía sentido.len
para verificar cadenas vacías / no vacías. Me gusta este compromiso de Brad Fitzpatrick. Me temo que todavía es una cuestión de gusto y claridad;)len(v) > 0
en h2_bundle.go (línea 2702). Creo que no se muestra automáticamente, ya que se genera desde golang.org/x/net/http2.Esto parece ser una microoptimización prematura. El compilador es libre de producir el mismo código para ambos casos o al menos para estos dos
y
porque la semántica es claramente igual.
fuente
Verificar la longitud es una buena respuesta, pero también podría tener en cuenta una cadena "vacía" que también es solo un espacio en blanco. No está "técnicamente" vacío, pero si le interesa verificar:
fuente
TrimSpace
asignará y copiará una nueva cadena de la cadena original, por lo que este enfoque introducirá ineficiencias a escala.s
es de tipo cadena,s[0:i]
devuelve una nueva copia. Las cadenas son inmutables en Go, entonces, ¿necesita crear una copia aquí?strings.TrimSpace( s )
no provocará una nueva asignación de cadena y copia de caracteres si la cadena no necesita recorte, pero si la cadena necesita recorte, se invocará la copia adicional (sin caracteres de espacio en blanco).gocritic
linter sugiere usar enstrings.TrimSpace(str) == ""
lugar de la verificación de longitud.Suponiendo que los espacios vacíos y todos los espacios en blanco iniciales y finales deben eliminarse:
Porque :
len("") // is 0
len(" ") // one empty space is 1
len(" ") // two empty spaces is 2
fuente
< 1
+1A partir de ahora, el compilador Go genera un código idéntico en ambos casos, por lo que es cuestión de gustos. GCCGo genera un código diferente, pero casi nadie lo usa, así que no me preocuparía por eso.
https://godbolt.org/z/fib1x1
fuente
Sería más limpio y menos propenso a errores usar una función como la siguiente:
fuente
Solo para agregar más para comentar
Principalmente sobre cómo hacer pruebas de rendimiento.
Hice pruebas con el siguiente código:
Y los resultados fueron:
Las variantes efectivas generalmente no alcanzan el tiempo más rápido y solo hay una diferencia mínima (aproximadamente 0.01ns / op) entre la velocidad máxima de la variante.
Y si miro el registro completo, la diferencia entre los intentos es mayor que la diferencia entre las funciones de referencia.
Además, no parece haber ninguna diferencia apreciable entre BenchmarkStringCheckEq y BenchmarkStringCheckNe o BenchmarkStringCheckLen y BenchmarkStringCheckLenGt, incluso si estas últimas variantes deberían aumentar 6 veces en lugar de 2 veces.
Puede intentar obtener algo de confianza sobre el mismo rendimiento agregando pruebas con prueba modificada o bucle interno. Esto es más rápido:
Esto no es más rápido:
Ambas variantes suelen ser más rápidas o más lentas que la diferencia entre las pruebas principales.
También sería bueno generar cadenas de prueba (ss) utilizando un generador de cadenas con distribución relevante. Y tienen longitudes variables también.
Por lo tanto, no tengo ninguna confianza en la diferencia de rendimiento entre los métodos principales para probar la cadena vacía en go.
Y puedo decir con cierta confianza, es más rápido no probar una cadena vacía que probar una cadena vacía. Y también es más rápido probar una cadena vacía que probar 1 cadena de caracteres (variante de prefijo).
fuente
Según las pautas oficiales y desde el punto de vista del rendimiento, parecen equivalentes ( respuesta ANisus ), s! = "" Sería mejor debido a una ventaja sintáctica. s! = "" fallará en tiempo de compilación si la variable no es una cadena, mientras que len (s) == 0 pasará por varios otros tipos de datos.
fuente
len()
requiere un poco de trabajo extra. SIN EMBARGO, una cosa que solíamos hacer en C era lanzar el lado izquierdo a unaconst
o colocar la cadena estática en el lado izquierdo del operador para evitar que s == "" se convierta en s = "", lo cual en la sintaxis de C es aceptable. .. y probablemente golang también. (ver el extendido si)Esto sería más eficaz que recortar toda la cadena, ya que solo necesita verificar al menos un carácter que no sea un espacio existente
fuente
Creo que la mejor manera es comparar con una cadena en blanco
BenchmarkStringCheck1 está comprobando con una cadena en blanco
BenchmarkStringCheck2 está comprobando con len zero
Compruebo con la comprobación de cadena vacía y no vacía. Puede ver que verificar con una cadena en blanco es más rápido.
Código
fuente