简体   繁体   English

StringBuilder真的比Aggreggate快吗?

[英]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 really 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? 我真正想做的是像string.Join(",",tmpArr[0]) ,但我不希望它连接他们的ToString值,只是他们的名字,我怎么能做到最好?

my problem with not using string.Join is I would actually have to do something like this: 我没有使用string.Join问题是我实际上必须做这样的事情:

        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; 如果在循环中追加字符串( c += m.Name + " "; ),则会导致创建大量中间字符串; this causes "telescopic" memory usage, and puts extra load on GC. 这会导致“伸缩”内存使用,并给GC带来额外负担。 Aggregate, mixed with the fluent-API of StringBuilder can help here - but as would looping with StringBuilder. Aggregate与StringBuilder的fluent-API混合在一起可以提供帮助 - 但是与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 更少; p

And for a similar example using StringBuilder in Aggregate: 对于在Aggregate中使用StringBuilder的类似示例:

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? 我不希望它连接他们的ToString值,只是他们的名字,我怎么能做到最好?

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

But most of the time It. 但大多数时候它。 Just. 只是。 Doesn't. 不。 Matter! 物!

Aggregate itself is not the problem. Aggregate本身不是问题。 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. 这就是为什么你应该使用StringBuilderJoin来避免这种情况。

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 . 如果你想使用Join和linq以获得更好的可读性,你仍然可以,不要使用Aggregate而是SelectToArray

As string is Immutable, add operation has performance cost. 由于字符串是不可变的,因此添加操作具有性能成本。 This is what the StringBuilder is mainly designed for, it acts like "Mutable" String. 这是StringBuilder主要设计的内容,它的作用类似于“Mutable”String。 I haven't done much benchmarking for the speed, but for memory optimizations StringBuilder is definitely better. 我没有对速度进行过多的基准测试,但对于内存优化,StringBuilder肯定更好。

Aggregate runs an anonymous method against each item in the IEnumerable . Aggregate针对IEnumerable中的每个项运行匿名方法。 This method is passed to the System-defined Func<> delegate which returns an out parameter. 此方法传递给系统定义的Func<>委托,该委托返回out参数。

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 因此,对于方法调用等,堆栈上的分配/释放肯定比运行简单的for / foreach循环有更多的开销

So, in my opinion the second method would be faster. 所以,在我看来, 第二种方法会更快。

像这样的东西?

string joined = string.Join(",", myItems.Select(x => x.Name).ToArray());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM