C#:并行的资源利用率

时间:2015-05-28 09:36:33

标签: c# string parallel-processing

我正在尝试在 Parallel For 中进行一次独特的检查,以使流程更快。这实际上会做我独特的检查吗?

以下是我的代码:

List<string> uniqueCheck = new List<string>();

Parallel.For(1, Rows.Length, i => {
    if (Rows[i].Length != 0)
    {
        string[] item = Rows[i].Split(delimiter.ToCharArray());

        if (!uniqueCheck.Contains(item[0].ToLower().Trim()))
        {
            uniqueCheck.Add(item[0].ToLower().Trim());
            dtUnqiueRows.Rows.Add(item);
        }
    }
});

我不确定 Parallel For 是如何工作的,但我想确定!uniqueCheck.Contains(...)条件是否会按预期工作。

如果这不起作用,请对此发表评论并发布任何代码。

1 个答案:

答案 0 :(得分:1)

我使用Guids制作了一些测试代码。 您想要使用Distinct()的原因是它将使用Hashset而不是列表来跟踪唯一项。 对于大行数,Hashset可能比您的uniqueCheck列表快得多。

正如您在结果中看到的那样,如果您编写guids.AsParallel,则比没有并行性要快一些,但如果您编写Select(....).AsParallel()则会慢一些。 以下是包含结果的代码:

修改:添加Select(... regex..)以创建包含更多&#34;密钥重复项的列表&#34;

   var guids = Enumerable.Range(1, 1600000).Select(_ => Guid.NewGuid().ToString().ToUpper()).ToList();
guids = guids.Select(g => Regex.Replace(g, @"^([0-9A-F])[^\-]+", "$1$1$1$1")).ToList();
var delimiters = "-".ToCharArray();
    var delimiters = "-".ToCharArray();

var w = Stopwatch.StartNew();
var x = guids.Select(guid => guid.Split(delimiters)[0].ToLower()).Distinct().ToList();
Console.WriteLine(w.Elapsed); // 1.80 seconds 

w = Stopwatch.StartNew();
var y = guids.Select(guid => guid.Split(delimiters)[0].ToLower()).AsParallel().Distinct().ToList();
Console.WriteLine(w.Elapsed); // 1.67 seconds 

w = Stopwatch.StartNew();
var z = guids.AsParallel().Select(guid => guid.Split(delimiters)[0].ToLower()).Distinct().ToList();
Console.WriteLine(w.Elapsed); // 0.75 seconds

修改:这是一个用唯一键选择第一行的解决方案

// for selecting the first row which has unique "key"

var w = Stopwatch.StartNew();
var a = guids.GroupBy(guid => guid.Split(delimiters)[0].ToLower()).Select(grp => grp.First()).ToList();
Console.WriteLine(w.Elapsed); // 0.65 seconds 

w = Stopwatch.StartNew();
var b = guids.AsParallel().GroupBy(guid => guid.Split(delimiters)[0].ToLower()).Select(grp => grp.First()).ToList();
Console.WriteLine(w.Elapsed); // 0.83 seconds