Медленная конкатенация строк по большому входу

Мне не нравится троичный (return a ? (b || c) : (b && c); из верхнего ответа), и я не думаю, что видел, чтобы кто-то упоминал об этом. Это написано так:

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    if (a) {
        return b||c;
    } 
    else {
        return b&&C;
    }
7
задан skaffman 14 July 2009 в 17:09
поделиться

6 ответов

Подобные конкатенации строк очень медленные. Используйте StringBuilder.

@Override
public String toString(){
        StringBuilder buffer = new StringBuilder();
        printTree(this, buffer);
        return buffer.toString();
}

public void printTree(AbstractTree<E> tree, StringBuilder buffer){
    if (tree.isLeaf()){
        buffer.append(tree.getNodeName());
    } else {
        buffer.append(tree.getNodeName());
        buffer.append("(");

        int i = 0;
        Iterator<AbstractTree<E>> child = tree.getChildren().iterator();
        while (i < tree.getChildren().size() - 1){
            printTree(child.next(), buffer);
            buffer.append(", ");
            i++;
        }
        printTree(child.next(), buffer); 
        buffer.append(")");
    }
}
17
ответ дан 6 December 2019 в 06:03
поделиться

Не используйте конкатенацию строк в циклах. Он не масштабируется.

Используйте StringBuilder, это не создает постоянно новые объекты, например конкатенацию строк ..

void print() {
StringBuilder sb = new StringBuilder();
sb.append("hello");
sb.append(" World!");
System.out.println(sb.toString());

}

5
ответ дан 6 December 2019 в 06:03
поделиться

Посмотрите на StringBuilder, не используйте простую конкатенацию и передавайте StringBuilder через весь процесс (или сделайте его глобальным).

3
ответ дан 6 December 2019 в 06:03
поделиться

Вы можете посмотреть на String.intern () как на способ сократить использование памяти. Это будет использовать интернированную строку из пула строк. Если у вас много повторяющихся строк, это может быть быстрее. Более подробная информация об интернированных строках здесь

-1
ответ дан 6 December 2019 в 06:03
поделиться

Если профилировщик подтверждает вам, что узким местом является конкатенация строк, у вас есть два варианта:

  • StringBuilder / StringBuffer (последний лучше подходит для многопоточности)
  • Веревки для Java :

Веревка - это высокоэффективная замена для строк. Структура данных, подробно описанная в статье «Веревки: альтернатива строкам», обеспечивает асимптотически лучшую производительность, чем String и StringBuffer, для общих модификаций строк, таких как добавление, добавление, удаление и вставка. Как и строки, связки неизменяемы и поэтому хорошо подходят для использования в многопоточном программировании.

2
ответ дан 6 December 2019 в 06:03
поделиться

Позвольте мне сказать, что конкатенация строк происходит медленно, потому что строки неизменяемы. Это означает, что каждый раз, когда вы пишете «+ =», создается новая строка. Это означает, что в худшем случае вы строите строку O (n 2 ). Это потому, что если вы + = 'ed по 1 символу за раз, стоимость построения новой строки будет 2 + 3 + 4 + ... + n, что составляет O (n 2 ).

​​Используйте StringBuilder, как предлагают другие (вместо более медленного, но потокобезопасного StringBuffer).

Я полагаю, я должен добавить, StringBuilder даст вам амортизированное время O (n), потому что он работает как вектор за кулисами, поскольку он изменчивый. Так что создайте там свою строку, а затем вызовите toString ().

StringBuilder builder = new StringBuilder();
builder.append("blah"); // append more as needed.
String text = builder.toString();

Я также хотел бы добавить, что эта проблема похожа на Python. Идиома в Python состоит в том, чтобы добавить все ваши строки для объединения в список, а затем присоединиться к списку. "". Join (the_list) .

ОБНОВЛЕНИЕ: Как указывает Билл, конкатенация не является корнем всего зла. Однострочные конкатенации хороши и даже могут быть оптимизированы! (Они также являются линейными в худшем случае). Но когда вы объединяете в цикл, как описано выше, производительность резко меняется с увеличением количества итераций. В этом случае мой приведенный выше анализ безупречен, поскольку я специально заявил, что это «худший случай», что означает, что вы не предполагаете никаких оптимизаций. (Что JVM не может даже оптимизировать конкатенацию в циклах так же хорошо, как снаружи).

конкатенация не является корнем всего зла. Однострочные конкатенации хороши и даже могут быть оптимизированы! (Они также являются линейными в худшем случае). Но когда вы объединяете в цикл, как указано выше, производительность резко меняется с увеличением количества итераций. В этом случае мой приведенный выше анализ безупречен, поскольку я специально заявил, что это «наихудший случай», что означает, что вы не предполагаете никаких оптимизаций. (Что JVM не может даже оптимизировать конкатенацию в циклах так же хорошо, как снаружи).

конкатенация не является корнем всего зла. Однострочные конкатенации хороши и даже могут быть оптимизированы! (Они также являются линейными в худшем случае). Но когда вы объединяете в цикл, как указано выше, производительность резко меняется с увеличением количества итераций. В этом случае мой приведенный выше анализ безупречен, поскольку я специально заявил, что это «худший случай», что означает, что вы не предполагаете никаких оптимизаций. (Что JVM не может даже оптимизировать конкатенацию в циклах так же хорошо, как снаружи).

как я специально сказал, это «наихудший случай», что означает, что вы не предполагаете никаких оптимизаций. (Что JVM не может даже оптимизировать конкатенацию в циклах так же хорошо, как снаружи).

как я специально сказал, это «наихудший случай», что означает, что вы не предполагаете никаких оптимизаций. (Что JVM не может даже оптимизировать конкатенацию в циклах так же хорошо, как снаружи).

4
ответ дан 6 December 2019 в 06:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: