Veja o exemplo abaixo:
static final int MAX_ITERATIONS = 50000;
static final int CALC_AVG_EVERY = 10000;
public static void main(String[] args) {
printBytecodeVersion();
printJavaVersion();
case1();//str.concat
case2();//+=
case3();//StringBuilder
}
static void case1() {
System.out.println("[str1.concat(str2)]");
List<Long> savedTimes = new ArrayList();
long startTimeAll = System.currentTimeMillis();
String str = "";
for (int i = 0; i < MAX_ITERATIONS; i++) {
long startTime = System.currentTimeMillis();
str = str.concat(UUID.randomUUID() + "---");
saveTime(savedTimes, startTime);
}
System.out.println("Created string of length:" + str.length() + " in " + (System.currentTimeMillis() - startTimeAll) + " ms");
}
static void case2() {
System.out.println("[str1+=str2]");
List<Long> savedTimes = new ArrayList();
long startTimeAll = System.currentTimeMillis();
String str = "";
for (int i = 0; i < MAX_ITERATIONS; i++) {
long startTime = System.currentTimeMillis();
str += UUID.randomUUID() + "---";
saveTime(savedTimes, startTime);
}
System.out.println("Created string of length:" + str.length() + " in " + (System.currentTimeMillis() - startTimeAll) + " ms");
}
static void case3() {
System.out.println("[str1.append(str2)]");
List<Long> savedTimes = new ArrayList();
long startTimeAll = System.currentTimeMillis();
StringBuilder str = new StringBuilder("");
for (int i = 0; i < MAX_ITERATIONS; i++) {
long startTime = System.currentTimeMillis();
str.append(UUID.randomUUID() + "---");
saveTime(savedTimes, startTime);
}
System.out.println("Created string of length:" + str.length() + " in " + (System.currentTimeMillis() - startTimeAll) + " ms");
}
static void saveTime(List<Long> executionTimes, long startTime) {
executionTimes.add(System.currentTimeMillis() - startTime);
if (executionTimes.size() % CALC_AVG_EVERY == 0) {
out.println("average time for " + executionTimes.size() + " concatenations: "
+ NumberFormat.getInstance().format(executionTimes.stream().mapToLong(Long::longValue).average().orElseGet(() -> 0))
+ " ms avg");
executionTimes.clear();
}
}
Resultado:
java bytecode versão: 8
java.version: 1.8.0_144
[str1.concat (str2)]
tempo médio para 10000 concatenações: 0,096 ms
tempo médio para 10000 concatenações: 0,185 ms
tempo médio para 10000 concatenações: 0,327 ms
tempo médio para 10000 concatenações: 0,501 ms
tempo médio para 10000 concatenações: 0,656 ms méd
. Sequência de caracteres criada de comprimento: 1950000 em 17745 ms
[str1 + = str2]
tempo médio para 10000 concatenações: 0,21 ms
tempo médio para 10000 concatenações: 0,652 ms
tempo médio para 10000 concatenações: 1.129 ms
tempo médio para 10000 concatenações: 1.727 ms
tempo médio para 10000 concatenações: 2,302 ms avg
Cadeia de comprimento criada: 1950000 em 60279 ms
[str1.append (str2)]
tempo médio para 10000 concatenações: 0,002 ms
tempo médio para 10000 concatenações: 0,002 ms
tempo médio para 10000 concatenações: 0,002 ms
tempo médio para 10000 concatenações: Tempo médio
médio de 0,002 ms para 10000 concatenações: 0,002 ms média de
sequência criada: 1950000 in 100 ms
À medida que o comprimento da cadeia aumenta, o tempo de concatenação também aumenta.
É aí que StringBuilder
definitivamente é necessário.
Como você vê, a concatenação:, UUID.randomUUID()+"---"
realmente não afeta o tempo.
PS: Eu não acho que quando usar o StringBuilder em Java seja realmente uma duplicata disso.
Esta pergunta fala sobre o toString()
que na maioria das vezes não executa concatenações de grandes seqüências de caracteres.
Atualização de 2019
Desde os java8
tempos, as coisas mudaram um pouco. Parece que agora (java13), o tempo de concatenação de +=
é praticamente o mesmo que str.concat()
. No entanto, o StringBuilder
tempo de concatenação ainda é constante . (A postagem original acima foi ligeiramente editada para adicionar uma saída mais detalhada)
java bytecode versão: 13
java.version: 13.0.1
[str1.concat (str2)]
tempo médio para 10000 concatenações: 0,047 ms
tempo médio para 10000 concatenações: 0,1 ms
tempo médio para 10000 concatenações: 0,17 ms
tempo médio para 10000 concatenações: 0,255 ms
tempo médio para 10000 concatenações: 0,336 ms méd
. Sequência de caracteres criada de comprimento: 1950000 em 9147 ms
[str1 + = str2]
tempo médio para 10000 concatenações: 0,037 ms
tempo médio para 10000 concatenações: 0,097 ms
tempo médio para 10000 concatenações: 0.249 ms
tempo médio para 10000 concatenações: 0.298 ms
tempo médio para 10000 concatenações: 0,326 ms avg
Cadeia de comprimento criada: 1950000 em 10191 ms
[str1.append (str2)]
tempo médio para 10000 concatenações: 0,001 ms
tempo médio para 10000 concatenações: 0,001 ms
tempo médio para 10000 concatenações: 0,001 ms
tempo médio para 10000 concatenações: Tempo médio
médio de 0,001 ms para 10000 concatenações: 0,001 ms média de
sequência criada: 1950000 in 43 ms
É importante notar que a bytecode:8/java.version:13
combinação tem um bom benefício de desempenho em comparação combytecode:8/java.version:8