Это цепочка StringBuilder.добавить более эффективно, чем конкатенация строк?


согласно намеку Netbeans с именем цепи использования .добавить методы вместо конкатенации строк

ищет конкатенацию строк в параметре вызова метода append метода StringBuilder или StringBuffer.

Является StringBuilder.добавить () действительно эффективнее, чем конкатенация строк?

пример кода

StringBuilder sb = new StringBuilder();
sb.append(filename + "/");

и

StringBuilder sb = new StringBuilder();
sb.append(filename).append("/");
6 51

6 ответов:

вы должны сбалансировать читаемость с функциональностью.

допустим, у вас есть следующее:

String str = "foo";
str += "bar";
if(baz) str += "baz";

это создаст 2 строковых строителя (где вам нужен только 1, на самом деле) плюс дополнительный строковый объект для промежуточного. Вы были бы более эффективны, если бы вы пошли:

StringBuilder strBuilder = new StringBuilder("foo");
strBuilder.append("bar");
if(baz) strBuilder.append("baz");
String str = strBuilder.toString();

но как вопрос стиля, я думаю, что первый выглядит просто отлично. Преимущество в производительности при создании одного объекта кажется мне очень минимальным. Теперь, если вместо 3 строк, у вас было 10, или 20, или 100, я бы сказал, что производительность перевешивает стиль. Если бы это было в цикле, конечно, я бы использовал строковый конструктор, но я думаю, что всего пара строк отлично подходит для "небрежного" способа сделать код более чистым. Но... это очень опасная ловушка скрывается в нем! Читайте ниже (пауза, чтобы построить ожидание... dun dun dunnnn)

есть те, кто говорит, чтобы всегда использовать явный строитель строк. Одной из причин является то, что ваш код будет продолжать расти, и обычно это будет делать так же, как и сейчас (т. е. они не будут тратить время на рефакторинг.) Таким образом, вы получаете эти 10 или 20 операторов, каждый из которых создает свой собственный конструктор, когда вам это не нужно. Поэтому, чтобы предотвратить это с самого начала, они говорят, что всегда используют явный строитель.

так что в вашем примере это не будет особенно быстро, когда кто-то в будущем решит, что им нужно расширение файла в конце, или что-то в этом роде, если они продолжают использовать строку конкатенация вместо StringBuilder, они в конечном итоге столкнутся с проблемами производительности.

нам также нужно думать о будущем. Предположим, вы делали Java-код в JDK 1.1, и у вас был следующий метод:

public String concat(String s1, String s2, String s3) {
    return s1 + s2 + s3;
}

в то время это было бы медленно, потому что StringBuilder не существовало.

затем в JDK 1.3 вы решили сделать это быстрее с помощью StringBuffer (StringBuilder еще не существует). Вы делаете это:

public String concat(String s1, String s2, String s3) {
    StringBuffer sb = new StringBuffer();
    sb.append(s1);
    sb.append(s2);
    sb.append(s3);
    return sb.toString();
}

это становится намного быстрее. Потрясающе!

теперь JDK 1.5 выходит, и с ним приходит StringBuilder (который быстрее, чем StringBuffer) и автоматическая передача

return s1 + s2 + s3;

до

return new StringBuilder().append(s1).append(s2).append(s3).toString();

но вы не получаете это преимущество производительности, потому что вы используете StringBuffer явно. Таким образом, будучи умным, вы вызвали хит производительности, когда Java стал умнее вас. Так что вы должны иметь в виду, что есть вещи, о которых вы не думаю.

Ну, ваш первый пример по существу переведен компилятором во что-то вроде:

StringBuilder sb = new StringBuilder();
sb.append(new StringBuilder().append(filename).append("/").toString());

Так что да, здесь есть определенная неэффективность. Однако, действительно ли это имеет значение в вашей программе-это другой вопрос. Помимо сомнительного стиля (подсказка: субъективный), это обычно имеет значение только в том случае, если вы делаете это в жесткой петле.

ни один из ответов до сих пор явно не касается конкретного случая, для которого предназначена подсказка. Это не говорит всегда использовать StringBuilder#append вместо конкатенации. Но, если вы уже используете StringBuilder, это не имеет смысла смешивать в конкатенации, потому что это создает избыточную StringBuilder (см. ответ Дирка) и ненужный временный String экземпляра.

несколько ответов уже обсуждают, почему предлагаемый способ более эффективен, но главное если у вас уже есть StringBuilder например, просто позвонить append на нем. Это так же читаемо (на мой взгляд, и, по-видимому, тот, кто написал намек NetBeans), так как вы звоните append в любом случае, и это немного более эффективным.

Теоретически, да. Поскольку строковые объекты неизменяемы: после их создания они больше не могут быть изменены. Поэтому использование " + " (конкатенация) в основном создает новый объект каждый раз.

практически нет. Компилятор достаточно умен, чтобы заменить все ваши "+" на приложения StringBuilder.

для более детального объяснения: http://kaioa.com/node/59

PS: Netbeans??? Ну же!

конкат из двух строк быстрее с помощью этой функции.

однако, если у вас есть несколько строк или другой тип данных, вы должны использовать StringBuilder явно или неявно. Используя + with Strings использует StringBuilder неявно.

Это только более эффективно, если вы используете много конкатенации и действительно длинные строки. Для общего использования, такого как создание имени файла в вашем примере, любая конкатенация строк просто прекрасна и более читаема.

во всяком случае, эта часть вашего приложения вряд ли будет узким местом производительности.