Какой метод конкатенации строк использовать для N числа итераций? - PullRequest
3 голосов
/ 12 октября 2009

Если я хочу объединить строку N раз, какой метод мне лучше выбрать?

Взять этот код в качестве примера:

public static string Repeat(this string instance, int times)
{
        var result = string.Empty;

        for (int i = 0; i < times; i++)
            result += instance;

        return result;
}

Этот метод может быть вызван со значением «times», равным 5 или 5000. Какой метод я предпочитаю использовать?

string.join? StringBuilder? Просто стандартная строка. Конкат?

Аналогичная функция будет реализована в коммерческой библиотеке, поэтому мне действительно нужен «оптимальный» способ сделать это.

Ответы [ 4 ]

8 голосов
/ 12 октября 2009
    public static string Repeat(this string instance, int times)
    {
        if (times == 1 || string.IsNullOrEmpty(instance)) return instance;
        if (times == 0) return "";
        if (times < 0) throw new ArgumentOutOfRangeException("times");
        StringBuilder sb = new StringBuilder(instance.Length * times);
        for (int i = 0; i < times; i++)
            sb.Append(instance);
        return sb.ToString();
    }
5 голосов
/ 12 октября 2009

Конечно же Stringbuilder. Он предназначен для быстрых операций объединения строк, поскольку он не будет создавать новый объект каждый раз, когда вы хотите присоединить строку.

Подробнее см. здесь .

2 голосов
/ 12 октября 2009

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

Удивительно, но для меньшего числа итераций обычная конкатенация строк (результат + = строка) часто быстрее, чем использование построителя строк.

Если вы знаете, что число итераций всегда будет одинаковым (например, это всегда будет 50 итераций), то я бы посоветовал вам сделать некоторые измерения производительности, используя разные методы.

Если вы действительно хотите стать умным, выполните измерения производительности по количеству итераций, и вы можете найти «точку пересечения», где один метод быстрее другого, и жестко закодировать этот порог в методе:

if(iterations < 30)
{
    CopyWithConcatenation();
}
else
{
    CopyWithStringBuilder();
}

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

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

Дайте нам знать, как вы попали.

2 голосов
/ 12 октября 2009

StringBuilder.

"результат + = результат;"

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

Иди с StringBuilder, определенно.

...