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
我正在尝试在 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