Действительно ли StringBuilder быстрее, чем Aggreggate? - PullRequest
3 голосов
/ 29 марта 2011
        string c = tmpArr[0].Aggregate(string.Empty, (current, m) => current + (m.Name + " "));

        StringBuilder sb = new StringBuilder();

        foreach (Mobile m in tmpArr[0])
            sb.Append(m.Name + " ");

        sb.ToString();

Какой из этих двух быстрее? агрегат, конечно, чище, но он быстрый или такой же, как и

foreach(Mobile m in tmpArr[0])
    c += m.Name + " ";

что я действительно хотел бы сделать, это что-то вроде string.Join(",",tmpArr[0]), но я не хочу, чтобы он соответствовал их значениям ToString, только их Именам, как бы я это сделал лучше всего?

Моя проблема с неиспользованием string.Join заключается в том, что мне действительно нужно сделать что-то вроде этого:

        string separator = "";
        StringBuilder sb = new StringBuilder();

        foreach (Mobile m in tmpArr[0])
        {
            separator = ", ";
            sb.Append(separator + m.Name);
        }

Ответы [ 6 ]

12 голосов
/ 29 марта 2011

Если вы добавляете строки в цикле (c += m.Name + " ";), вы вызываете создание множества промежуточных строк; это вызывает «телескопическое» использование памяти и создает дополнительную нагрузку на ГХ. Агрегат, смешанный с fluent-API StringBuilder, может помочь здесь - но, как и в случае с StringBuilder. Важно не значение Aggregate: оно не создает много промежуточных строк .

Например, я бы использовал:

foreach (Mobile m in tmpArr[0])
        sb.Append(m.Name).Append(" ");

еще меньше; p

И для аналогичного примера использования StringBuilder в Aggregate:

string c = tmpArr[0].Aggregate(new StringBuilder(),
    (current, m) => current.Append(m.Name).Append(" ")).ToString();
10 голосов
/ 29 марта 2011

Я не хочу, чтобы он объединял их значения ToString, только их Имена, как бы я это сделал лучше всего?

string.Join(",",tmpArr[0].Select(t => t.Name).ToArray())

Но большую часть времени It.Просто.Не имеет.Matter!

1 голос
/ 29 марта 2011

Как то так?

string joined = string.Join(",", myItems.Select(x => x.Name).ToArray());
1 голос
/ 29 марта 2011

Aggregate запускает анонимный метод для каждого элемента в IEnumerable. Этот метод передается определенному системой делегату Func<>, который возвращает выходной параметр.

Это в основном похоже на запуск функции, которая выполняет добавление столько раз.

Таким образом, распределение / освобождение в стеке для вызовов методов и т. Д., Безусловно, требует больше затрат, чем простой for / foreach цикл

Итак, на мой взгляд, второй метод будет быстрее.

1 голос
/ 29 марта 2011

Поскольку строка неизменна, операция добавления имеет снижение производительности.Это то, для чего в основном предназначен StringBuilder, он действует как "Mutable" String.Я не сделал много тестов для скорости, но для оптимизации памяти StringBuilder определенно лучше.

1 голос
/ 29 марта 2011

Aggregate сама не проблема. Проблема в том, что вы объединяете строки в цикле. Когда вы объединяете две строки с оператором +, в памяти должно быть выделено новое место, и две строки копируются в него. Поэтому, если вы используете + пять раз, вы на самом деле создаете пять новых строк. Вот почему вы должны использовать StringBuilder или Join, чтобы избежать этого.

Если вы хотите использовать Join вместе с linq для лучшей читабельности, вы все равно можете, просто не используйте Aggregate, но что-то вроде Select и ToArray.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...