我正在尝试在 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(...)条件是否会按预期工作。
如果这不起作用,请对此发表评论并发布任何代码。
答案 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