В настоящее время и StringBuffer, и Builder являются бесполезными (с точки зрения производительности).Я объясняю, почему:
StringBuilder должен был работать быстрее, чем StringBuffer, но любая здравомыслящая JVM может оптимизировать синхронизацию.Таким образом, это был довольно большой промах (и небольшой удар), когда он был представлен.
StringBuffer использовал NOT для копирования char [] при создании String (в необщем варианте);однако это было основным источником проблем, включая утечку огромного символа [] для маленьких строк.В 1.5 они решили, что копия char [] должна появляться каждый раз, и это фактически делает StringBuffer бесполезным (синхронизация была там, чтобы гарантировать, что никакие потоковые игры не смогут обмануть String).Это экономит память, хотя и в конечном итоге помогает GC (помимо явно уменьшенного занимаемого места), обычно char [] - это топ3 объектов, потребляющих память.
String.concat был и остается самым быстрым способом объединения2 строки (и только 2 ... или, возможно, 3).Имейте в виду, что он не выполняет дополнительную копию char [].
Возвращаясь к бесполезной части, теперь любой сторонний код может достичь той же производительности, что и StringBuilder.Даже в java1.1 у меня было имя класса AsycnStringBuffer, которое выполняло в точности то же самое, что и StringBuilder, но все равно выделяет больший char [], чем StringBuilder.Оба StrinBuffer / StringBuilder оптимизированы для небольших строк. По умолчанию вы можете видеть c-tor
StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
Таким образом, если вторая строка длиннее 16 символов, она получает еще одну копию основного символа [].Довольно не круто.
Это может быть побочным эффектом от попытки подгонки StringBuilder / Buffer и char [] в одну строку кэша (на x86) в 32-битной ОС ... но я не знаю, для чегоконечно.
Что касается примечаний о часах отладки и т. д. Используйте ваше мнение, я лично не припоминаю, чтобы когда-либо возникали какие-либо проблемы с операциями со строками, за исключением импл.структура, аналогичная веревке, для генератора sql JDO impl.
Редактировать: Ниже я проиллюстрирую то, что java-дизайнеры не делали для ускорения операций с String.Обратите внимание, что класс предназначен для пакета java.lang, и его можно поместить туда, только добавив его в путь к начальной загрузке.Однако, даже если этого не сделать (разница состоит из одной строки кода!), Это все равно будет быстрее, чем StringBuilder, шокирует?Класс сделал бы string1 + string2 + ... намного лучше, чем использование StringBuilder, но хорошо ...
package java.lang;
public class FastConcat {
public static String concat(String s1, String s2){
s1=String.valueOf(s1);//null checks
s2=String.valueOf(s2);
return s1.concat(s2);
}
public static String concat(String s1, String s2, String s3){
s1=String.valueOf(s1);//null checks
s2=String.valueOf(s2);
s3=String.valueOf(s3);
int len = s1.length()+s2.length()+s3.length();
char[] c = new char[len];
int idx=0;
idx = copy(s1, c, idx);
idx = copy(s2, c, idx);
idx = copy(s3, c, idx);
return newString(c);
}
public static String concat(String s1, String s2, String s3, String s4){
s1=String.valueOf(s1);//null checks
s2=String.valueOf(s2);
s3=String.valueOf(s3);
s4=String.valueOf(s4);
int len = s1.length()+s2.length()+s3.length()+s4.length();
char[] c = new char[len];
int idx=0;
idx = copy(s1, c, idx);
idx = copy(s2, c, idx);
idx = copy(s3, c, idx);
idx = copy(s4, c, idx);
return newString(c);
}
private static int copy(String s, char[] c, int idx){
s.getChars(c, idx);
return idx+s.length();
}
private static String newString(char[] c){
return new String(0, c.length, c);
//return String.copyValueOf(c);//if not in java.lang
}
}