Qual método é o melhor (mais idomatic) para testar seqüências de caracteres não vazias (no Go)?
if len(mystring) > 0 { }
Ou:
if mystring != "" { }
Ou alguma outra coisa?
Ambos os estilos são usados nas bibliotecas padrão do Go.
if len(s) > 0 { ... }
pode ser encontrado no strconv
pacote: http://golang.org/src/pkg/strconv/atoi.go
if s != "" { ... }
pode ser encontrado no encoding/json
pacote: http://golang.org/src/pkg/encoding/json/encode.go
Ambos são idiomáticos e são claros o suficiente. É mais uma questão de gosto pessoal e clareza.
Russ Cox escreve em um tópico de golang-nuts :
Aquele que torna o código claro.
Se estou prestes a olhar para o elemento x, normalmente escrevo
len (s)> x, mesmo para x == 0, mas se me preocupo com
"é essa sequência específica", tendem a escrever s == "".É razoável supor que um compilador maduro compile
len (s) == 0 es == "" no mesmo código eficiente.
...Faça o código claro.
Como apontado na resposta de Timmmm , o compilador Go gera código idêntico nos dois casos.
if mystring != "" { }
é a melhor, preferida e idiomática maneira HOJE. A razão pela qual a biblioteca padrão contém o contrário é porque ela foi escrita antes de 2010 quando alen(mystring) == 0
otimização fazia sentido.len
para verificar cadeias vazias / não vazias. Como este cometido por Brad Fitzpatrick. Receio que ainda é uma questão de gosto e clareza;)len(v) > 0
no h2_bundle.go (linha 2702). Não é mostrado automaticamente, pois é gerado a partir de golang.org/x/net/http2, acredito.Parece microoptimização prematura. O compilador é livre para produzir o mesmo código para os dois casos ou pelo menos para esses dois
e
porque a semântica é claramente igual.
fonte
A verificação do comprimento é uma boa resposta, mas você também pode ter uma string "vazia" que também é apenas espaço em branco. Não "tecnicamente" vazio, mas se você deseja verificar:
fonte
TrimSpace
alocará e copiará uma nova string da string original; portanto, essa abordagem introduzirá ineficiências em escala.s
tipo string,s[0:i]
retornar uma nova cópia. As strings são imutáveis no Go, então é necessário criar uma cópia aqui?strings.TrimSpace( s )
não causará nova alocação de string e cópia de caracteres se a string não precisar de aparar, mas se a string precisar de aparar, a cópia extra (sem caracteres de espaço em branco) será chamada.gocritic
linter sugere usar emstrings.TrimSpace(str) == ""
vez da verificação de comprimento.Supondo que os espaços vazios e todos os espaços em branco iniciais e finais devem ser removidos:
Porque :
len("") // is 0
len(" ") // one empty space is 1
len(" ") // two empty spaces is 2
fonte
< 1
+1A partir de agora, o compilador Go gera código idêntico nos dois casos, portanto é uma questão de gosto. O GCCGo gera código diferente, mas quase ninguém o usa, então eu não me preocuparia com isso.
https://godbolt.org/z/fib1x1
fonte
Seria mais limpo e menos propenso a erros usar uma função como a abaixo:
fonte
Apenas para adicionar mais para comentar
Principalmente sobre como fazer testes de desempenho.
Eu testei com o seguinte código:
E os resultados foram:
As variantes efetivamente geralmente não atingem o tempo mais rápido e há apenas uma diferença mínima (cerca de 0,01ns / op) entre a velocidade máxima da variante.
E se eu olhar o log completo, a diferença entre as tentativas é maior que a diferença entre as funções de benchmark.
Também não parece haver nenhuma diferença mensurável entre BenchmarkStringCheckEq e BenchmarkStringCheckNe ou BenchmarkStringCheckLen e BenchmarkStringCheckLenGt, mesmo que as últimas variantes devam aumentar c 6 vezes em vez de 2 vezes.
Você pode tentar obter alguma confiança sobre desempenho igual adicionando testes com teste modificado ou loop interno. Isso é mais rápido:
Isso não é mais rápido:
Ambas as variantes são geralmente mais rápidas ou mais lentas que a diferença entre os testes principais.
Também seria bom gerar strings de teste (ss) usando gerador de strings com distribuição relevante. E tem comprimentos variáveis também.
Portanto, não tenho nenhuma confiança na diferença de desempenho entre os métodos principais para testar a string vazia em movimento.
E posso afirmar com alguma confiança: é mais rápido não testar a string vazia do que testar a string vazia. E também é mais rápido testar uma string vazia do que testar uma string de char (variante de prefixo).
fonte
De acordo com as diretrizes oficiais e do ponto de vista do desempenho, elas parecem equivalentes ( resposta do ANisus ), o s! = "" Seria melhor devido a uma vantagem sintática. s! = "" falhará no tempo de compilação se a variável não for uma string, enquanto len (s) == 0 passará por vários outros tipos de dados.
fonte
len()
preciso apenas um pouco de trabalho extra. No entanto, uma coisa que costumávamos fazer em C era converter o lado esquerdo em aconst
ou colocar a string estática no lado esquerdo do operador para impedir que s == "" se tornasse s = "", o que na sintaxe C é aceitável. .. e provavelmente golang também. (veja o estendido se)Isso seria mais eficiente do que aparar toda a cadeia, pois você só precisa verificar se há pelo menos um único caractere não espacial
fonte
Eu acho que a melhor maneira é comparar com a string em branco
BenchmarkStringCheck1 está verificando com uma string em branco
BenchmarkStringCheck2 está verificando com len zero
Verifico com a verificação de cadeia vazia e não vazia. Você pode ver que a verificação com uma sequência em branco é mais rápida.
Código
fonte