Is StringBuilder really faster than Aggreggate?
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();
which of those two is faster? aggregate certainly is cleaner, but is it fast or is it the same as doing
foreach(Mobile m in tmpArr[0])
c += m.Name + " ";
what I 开发者_如何学Creally would like to do is something like string.Join(",",tmpArr[0])
, but I don't want it to concat their ToString values, just their Names, how would I do that best?
my problem with not using string.Join
is I would actually have to do something like this:
string separator = "";
StringBuilder sb = new StringBuilder();
foreach (Mobile m in tmpArr[0])
{
separator = ", ";
sb.Append(separator + m.Name);
}
If you append strings in a loop (c += m.Name + " ";
) you are causing lots of intermediate strings to be created; this causes "telescopic" memory usage, and puts extra load on GC. Aggregate, mixed with the fluent-API of StringBuilder can help here - but as would looping with StringBuilder. It isn't Aggregate that is important: it is not creating lots of intermediate strings.
For example, I would use:
foreach (Mobile m in tmpArr[0])
sb.Append(m.Name).Append(" ");
even fewer ;p
And for a similar example using StringBuilder in Aggregate:
string c = tmpArr[0].Aggregate(new StringBuilder(),
(current, m) => current.Append(m.Name).Append(" ")).ToString();
I don't want it to concat their ToString values, just their Names, how would I do that best?
string.Join(",",tmpArr[0].Select(t => t.Name).ToArray())
But most of the time It. Just. Doesn't. Matter!
As string is Immutable, add operation has performance cost. This is what the StringBuilder is mainly designed for, it acts like "Mutable" String. I haven't done much benchmarking for the speed, but for memory optimizations StringBuilder is definitely better.
Aggregate
runs an anonymous method against each item in the IEnumerable
. This method is passed to the System-defined Func<>
delegate which returns an out parameter.
It's basically like running a function that does the appending as many times.
So allocation/deallocation on the stack for the method calls etc certainly has more overhead than running a simple for
/foreach
loop
So, in my opinion the second method would be faster.
Aggregate
itself is not the problem. The problem is you are concatenating strings in a loop. When you concatenate two strings with +
operator, a new place must be allocated in memory and the two strings are copied into it. So if you use the +
five times, you actually create five new strings. That's why you should use StringBuilder
or Join
which avoid this.
If you want to use Join
along with linq for better readability, you still can, just don't use Aggregate
but something like Select
and ToArray
.
Something like this?
string joined = string.Join(",", myItems.Select(x => x.Name).ToArray());
精彩评论