Existe uma diferença perceptível entre o uso String.format
e a concatenação de String em Java?
Costumo usar, String.format
mas ocasionalmente escorregar e usar uma concatenação. Fiquei me perguntando se um era melhor que o outro.
A meu ver, String.format
lhe dá mais poder em "formatar" a string; e concatenação significa que você não precisa se preocupar em adicionar acidentalmente% s ou perder um.
String.format
também é mais curto.
Qual é mais legível depende de como sua cabeça funciona.
java
string
concatenation
string.format
Omar Kooheji
fonte
fonte
Respostas:
Eu sugeriria que é uma prática melhor usar
String.format()
. O principal motivo é queString.format()
pode ser mais facilmente localizado com o texto carregado de arquivos de recursos, enquanto a concatenação não pode ser localizada sem produzir um novo executável com código diferente para cada idioma.Se você planeja que seu aplicativo seja localizável, também deve adquirir o hábito de especificar posições de argumento para seus tokens de formato:
Em seguida, isso pode ser localizado e os tokens de nome e hora são trocados sem a necessidade de uma recompilação do executável para levar em conta as diferentes ordens. Com posições de argumento, você também pode reutilizar o mesmo argumento sem passá-lo para a função duas vezes:
fonte
Sobre o desempenho:
Os resultados do tempo são os seguintes:
Portanto, a concatenação é muito mais rápida que String.format.
fonte
javap -c StringTest.class
verá que o compilador converte "+" para StringBuilder automaticamente somente se você não estiver em um loop. Se a concatenação for feita em uma única linha, é o mesmo que usar '+', mas se você usarmyString += "morechars";
oumyString += anotherString;
em várias linhas, perceberá que mais de um StringBuilder pode ser criado, portanto, usar "+" nem sempre é tão eficiente como StringBuilder.+
não é convertido em,StringBuilder.append()
masnew StringBuilder()
ocorre um em cada iteração.Como há discussões sobre desempenho, achei que acrescentaria uma comparação que incluía StringBuilder. Na verdade, é mais rápido que o concat e, naturalmente, a opção String.format.
Para tornar isso uma espécie de comparação de maçãs com maçãs, instanciamos um novo StringBuilder no loop, e não no exterior (isso é realmente mais rápido do que fazer apenas uma instancia, provavelmente devido à sobrecarga de reatribuir espaço para o loop acrescentado no final de um construtor).
fonte
String
. O teste StringBuilder, para ser justo, precisa de uma etapa final que transforma o conteúdo do StringBuilder em uma String. Você faz isso ligandobldString.toString()
. Espero que isso explique?String s = bldString.toString();
Os horários foram com concatenação e stringbuilder quase a par com o outro:Format = 1520 millisecond
,Concatenation = 167 millisecond
,String Builder = 173 millisecond
eu corri-los em um loop e em média cada um para obter uma boa reputação: (otimização pré-jvm, vai tentar um loop 10000 + quando eu chegar em tempo)Um problema
.format
é que você perde a segurança do tipo estático. Você pode ter muito poucos argumentos para o seu formato e tipos incorretos para os especificadores de formato - ambos levando a umIllegalFormatException
tempo de execução , portanto, você pode acabar com o código de log que interrompe a produção.Por outro lado, os argumentos para
+
podem ser testados pelo compilador.O histórico de segurança deprintf(na qual a
format
função é modelada) é longa e assustadora.fonte
Você tem sua resposta aqui.
É uma questão de gosto pessoal.
A concatenação de strings é marginalmente mais rápida, suponho, mas isso deve ser insignificante.
fonte
Aqui está um teste com vários tamanhos de amostra em milissegundos.
}
fonte
Aqui está o mesmo teste acima, com a modificação da chamada do método toString () no StringBuilder . Os resultados abaixo mostram que a abordagem StringBuilder é um pouco mais lenta que a concatenação de String usando o operador + .
arquivo: StringTest.java
Comandos do shell: (compile e execute o StringTest 5 vezes)
Resultados :
fonte
String.format()
é mais do que concatenar seqüências de caracteres. Por exemplo, você pode exibir números em uma localidade específica usandoString.format()
.No entanto, se você não se importa com a localização, não há diferença funcional. Talvez um seja mais rápido que o outro, mas na maioria dos casos será insignificante.
fonte
Geralmente, a concatenação de strings deve ser preferida
String.format
. Este último tem duas principais desvantagens:No ponto 1, quero dizer que não é possível entender o que uma
String.format()
chamada está fazendo em uma única passagem seqüencial. Um é forçado a ir e voltar entre a string de formato e os argumentos, enquanto conta a posição dos argumentos. Para concatenações curtas, isso não é um problema. Nesses casos, no entanto, a concatenação de strings é menos detalhada.Por ponto 2, quero dizer que a parte importante do processo de construção está codificada na cadeia de formato (usando uma DSL). O uso de strings para representar código tem muitas desvantagens. Não é inerentemente seguro para o tipo e complica o destaque de sintaxe, a análise de código, a otimização etc.
Obviamente, ao usar ferramentas ou estruturas externas à linguagem Java, novos fatores podem entrar em jogo.
fonte
Não fiz benchmarks específicos, mas acho que a concatenação pode ser mais rápida. String.format () cria um novo Formatador que, por sua vez, cria um novo StringBuilder (com um tamanho de apenas 16 caracteres). Essa é uma quantidade considerável de sobrecarga, especialmente se você estiver formatando uma string mais longa e o StringBuilder continuar tendo que redimensionar.
No entanto, a concatenação é menos útil e mais difícil de ler. Como sempre, vale a pena fazer uma referência no seu código para ver qual é o melhor. As diferenças podem ser desprezíveis no aplicativo do servidor depois que seus pacotes de recursos, localidades etc. são carregados na memória e o código é JITted.
Talvez como prática recomendada, seria uma boa idéia criar seu próprio Formatador com um StringBuilder (Appendable) e um Localidade de tamanho adequado e usá-lo se você tiver muita formatação para fazer.
fonte
Pode haver uma diferença perceptível.
String.format
é bastante complexo e usa uma expressão regular por baixo; portanto, não use o hábito de usá-lo em qualquer lugar, mas apenas onde você precisar.StringBuilder
seria uma ordem de magnitude mais rápida (como alguém aqui já apontou).fonte
Acho que podemos seguir em frente
MessageFormat.format
, pois deve ser bom tanto na legibilidade quanto no desempenho.Usei o mesmo programa usado por Icaro na resposta acima e aprimorei-o com o código anexado
MessageFormat
para explicar os números de desempenho.ATUALIZAÇÕES:
De acordo com o Relatório SonarLint, as seqüências de caracteres no formato Printf devem ser usadas corretamente (squid: S3457)
Como as
printf-style
seqüências de formato são interpretadas em tempo de execução, em vez de validadas pelo compilador, elas podem conter erros que resultam na criação de seqüências de caracteres erradas. Esta regra estaticamente valida a correlação deprintf-style
seqüências de formato para os seus argumentos ao chamar os métodos formato (...) dejava.util.Formatter
,java.lang.String
,java.io.PrintStream
,MessageFormat
, ejava.io.PrintWriter
as classes e osprintf(...)
métodos dejava.io.PrintStream
oujava.io.PrintWriter
classes.Substituo o estilo printf pelos colchetes e obtive resultados interessantes como abaixo.
Conclusão:
Como destaquei acima, usar String.format com colchetes deve ser uma boa opção para obter benefícios de boa legibilidade e também desempenho.
fonte
Você não pode comparar Concatenação de String e String.Format pelo programa acima.
Você pode tentar isso também trocando a posição de usar sua String.Format e Concatenation no seu bloco de código como abaixo
Você ficará surpreso ao ver que o formato funciona mais rápido aqui. Isso ocorre porque os objetos iniciais criados podem não ser liberados e pode haver um problema com a alocação de memória e, portanto, o desempenho.
fonte
Demora um pouco para se acostumar com o String.Format, mas na maioria dos casos vale a pena. No mundo da NRA (nunca repita nada), é extremamente útil manter suas mensagens tokenizadas (log ou usuário) em uma biblioteca Constant (prefiro o que equivale a uma classe estática) e chamá-las conforme necessário com String.Format, independentemente de você estão localizando ou não. Tentar usar essa biblioteca com um método de concatenação é mais difícil de ler, solucionar problemas, revisar e gerenciar com qualquer abordagem que exija concatenação. A substituição é uma opção, mas duvido que tenha desempenho. Depois de anos de uso, meu maior problema com o String.Format é que a duração da chamada é inconvenientemente longa quando eu a passo para outra função (como Msg), mas é fácil usar uma função personalizada para servir como um alias .
fonte