C# 使用PLINQ或与保持原始顺序并行
我收集了大量的元素。我想为每个元素调用ToString并构建一个字符串。 我的第一个方法是放慢速度C# 使用PLINQ或与保持原始顺序并行,c#,parallel-processing,plinq,C#,Parallel Processing,Plinq,我收集了大量的元素。我想为每个元素调用ToString并构建一个字符串。 我的第一个方法是放慢速度 string str = ""; list.ForEach( g => { string s = g.ToString(); if(s != "") str = str + g.ToString() + "\n"; }); 我尝试使用如下所示的并行类和PLIN
string str = "";
list.ForEach( g => {
string s = g.ToString();
if(s != "")
str = str + g.ToString() + "\n";
});
我尝试使用如下所示的并行类和PLINQ,但最终字符串中元素的顺序与原始字符串不同
平行的
System.Threading.Tasks.Parallel.ForEach(list, g => {
string s = g.ToString();
if(s != "")
str = str + g.ToString() + "\n";
});
普林克
如何提高性能并保持原有秩序?
谢谢我认为在这里尝试使用并行不是正确的解决方案,使用更好的算法才是 目前,您的代码是(n2),因为每次串联都会创建一个全新的字符串,因此它必须将以前的整个字符串复制到新字符串中 但是,如果使用可变的
StringBuilder
而不是不可变的string
,则可以从O(n)开始执行此操作。这样,您只需在现有的StringBuilder
末尾追加,而无需复制任何内容
您还可以使用一种只用于将字符串连接在一起的特殊方法,以更少的代码实现相同的性能:string.Join()
但可能有更好的解决方案:使用
StreamWriter
。例如,如果您想将结果字符串写入文件,这将是一个更好的解决方案,因为整个字符串根本不需要在内存中
并行性并不能神奇地解决所有性能问题。您需要考虑线程将要做什么,特别是如果您的代码中有一些共享数据(如
str
)。在您的例子中,您可以尝试使用并行性,但它不会那么简单,而且我不确定它是否真的会提高性能
它的工作原理是这样的:每个线程将在列表中获得一系列索引,并将它们连接起来。最后,主线程将把所有线程的结果连接在一起。但是没有内置的方法,所以您需要自己编写所有代码。(这是可行的,因为字符串连接是。)
AsOrdered()
只保留原始顺序的顺序。因此,如果ForEach之后的顺序不同,那么您需要在之后对其进行排序。我不知道如何保持顺序(或者即使可能),但您应该使用StringBuilder,而不是串联字符串。更改为使用StringBuilder,而无需并行,从而解决了问题。谢谢大家
string str = "";
list.AsParallel().AsOrdered().ForAll( g => {
string s = g.ToString();
if(s != "")
str = str + g.ToString() + "\n";
});