Дивіться приклад нижче:
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();
}
}
Вихід:
версія байт-коду Java: 8
java.version: 1.8.0_144
[str1.concat (str2)]
середній час для 10000 конкатенацій: 0,06 мс
середній час середнього часу для 10000 конкатенацій: 0,185 мс
середній час для 10000 конкатенацій: 0,327 мс середній
середній час для 10000 конкатенацій: 0.501 мс
середній час середнього за 10000 конкатенацій: 0.656 мс сер.
Створений рядок довжиною: 1950000 в 17745 мс
[str1 + = str2]
середній час для 10000 конкатенацій:
середній час 0,21 мс середній час для 10000 конкатенацій: 0,652 мс середній
середній час для 10000 конкатенацій: 1.129 мс
середній час для 10000 конкатенацій: середньо 1.727 мс
середній час для 10000 конкатенацій: 2.302 мс сер.
Створений рядок довжиною: 1950000 за 60279 мс
[str1.append (str2)]
середній час для 10000 конкатенацій: 0,002 мс
середній час середнього часу для 10000 конкатенацій: 0,002 мс середній
середній час для 10000 конкатенацій:
Середній час 0,002 мс середній час для 10000 конкатенацій: 0,002 мс
середній час середнього часу для 10000 конкатенацій: 0,002 мс середній
Створений рядок довжиною: 1950000 в 100 мс
Зі збільшенням довжини рядка збільшується і час конкатенації.
Саме тут StringBuilder
, безумовно, потрібно.
Як бачите, конкатенація:, UUID.randomUUID()+"---"
насправді не впливає на час.
PS: Я не думаю, що коли використовувати StringBuilder на Java , насправді це дублікат.
Це питання говорить про те, toString()
яке більшість разів не виконує конкатекації величезних струн.
Оновлення 2019 року
З java8
часів справи дещо змінилися. Здається, що зараз (java13) час конкатенації +=
практично такий же, як і str.concat()
. Однак StringBuilder
час конкатенації все ще постійний . (Оригінальна публікація вище була трохи відредагована, щоб додати більше детального виводу)
версія байт-коду java: 13
java.version: 13.0.1
[str1.concat (str2)]
середній час для 10000 конкатенацій: 0,047 ms
середній час для 10000 конкатенацій: 0,1 мс
середній час для 10000 конкатенацій: 0,17 мс середній
середній час для 10000 конкатенацій:
середній час 0,255 мс середній час для 10000 конкатенацій: 0,336 мс сер.
Створений рядок довжиною: 1950000 в 9147 мс
[str1 + = str2]
середній час для 10000 конкатенацій: 0,037 мс
середній час для 10000 конкатенацій: 0,097 мс середній
середній час за 10000 конкатенацій:
середній час 0,249 мс середній час для 10000 конкатенацій: серп. 0,298 мс
середній час для 10000 конкатенацій: 0,326 мс сер.
Створений рядок довжиною: 1950000 за 10191 мс
[str1.append (str2)]
середній час для 10000 конкатенацій: 0,001 мс
середній час середнього часу для 10000 конкатенацій: 0,001 мс середній
середній час для 10000 конкатенацій:
Середній час 0,001 мс середнього часу для 10000 конкатенацій: 0,001 мс
середній час середнього часу для 10000 конкатенацій: 0,001 мс середній
Створений рядок довжиною: 1950000 за 43 мс
Варто зауважити, що bytecode:8/java.version:13
комбінація має хороші переваги щодо продуктивностіbytecode:8/java.version:8