C#:Parallel For 中的资源利用

C#: Resource utilization in Parallel For

我正在尝试在 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(...) 条件是否会按预期工作。

请对此发表评论,如果这行不通,请 post 任何代码。

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

正如您在结果中看到的那样,如果您编写 guids.AsParallel,它比没有并行性稍微快一些,但如果您编写 Select(....).AsParallel(),则速度较慢。 这是带有结果的代码:

编辑:添加了Select(... regex..)以创建包含更多"key duplicates"

的列表
   var guids = Enumerable.Range(1, 1600000).Select(_ => Guid.NewGuid().ToString().ToUpper()).ToList();
guids = guids.Select(g => Regex.Replace(g, @"^([0-9A-F])[^\-]+", "")).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