我有很多元素。我想为每个元素调用ToString并构建一个字符串。 我的第一个方法是放慢速度
string str = "";
list.ForEach( g => {
string s = g.ToString();
if(s != "")
str = str + g.ToString() + "\n";
});
我尝试使用Parallel类和PLINQ,如下所示,但最终字符串中元素的顺序与原始字符串不同。
并行
System.Threading.Tasks.Parallel.ForEach(list, g => {
string s = g.ToString();
if(s != "")
str = str + g.ToString() + "\n";
});
PLINQ
string str = "";
list.AsParallel().AsOrdered().ForAll( g => {
string s = g.ToString();
if(s != "")
str = str + g.ToString() + "\n";
});
如何提高性能并保持原始订单? 感谢
答案 0 :(得分:0)
我认为尝试使用并行性不是正确的解决方案,使用更好的算法是。
目前,您的代码为O( n 2 ),因为每个连接都会创建一个全新的字符串,因此必须复制整个以前的字符串进入新的。
但如果使用可变StringBuilder
而不是不可变string
,则可以使用O(n)进行此操作。这样,您可以在现有StringBuilder
的末尾追加,而不必复制任何内容。
使用特殊方法只需将字符串连接在一起,您也可以用更少的代码实现相同的性能:string.Join()
。
但可能有更好的解决方案:使用StreamWriter
。例如,如果您想将结果字符串写入文件,那将是一个更好的解决方案,因为整个字符串根本不需要在内存中。
并行性不会神奇地解决所有性能问题。您需要考虑线程将要做什么,特别是如果您有一些共享数据(例如代码中的str
)。在你的情况下,可以尝试使用并行性,但它不会那么简单,我不确定它是否会真正提高性能。
它会像这样工作:每个线程将获得列表中的一系列索引并连接它们。最后,主线程将所有线程的结果连接在一起。但是没有内置的方法,所以你需要自己编写所有代码。 (这样可行,因为字符串连接是associative。)