C# 基于属性迭代和设置计数器的快速方法
我想遍历一个具有一些典型属性的自定义类的列表。 该列表将是巨大且不断增长的(从3000个项目开始,可能达到+10k) 我正在阅读关于快速迭代和检查属性的最佳方法,因为我将填充一些计数器 但是如果我需要按照逻辑检查这些属性。。。什么会更快 目前,我的代码如下所示:C# 基于属性迭代和设置计数器的快速方法,c#,loops,parallel-processing,C#,Loops,Parallel Processing,我想遍历一个具有一些典型属性的自定义类的列表。 该列表将是巨大且不断增长的(从3000个项目开始,可能达到+10k) 我正在阅读关于快速迭代和检查属性的最佳方法,因为我将填充一些计数器 但是如果我需要按照逻辑检查这些属性。。。什么会更快 目前,我的代码如下所示: public void CalculateTotalCounters() { #region ParallelCounting countTotal = 0; countMapped = 0;
public void CalculateTotalCounters()
{
#region ParallelCounting
countTotal = 0;
countMapped = 0;
countNotMapped = 0;
countError = 0;
errorFound = false;
MyList.AsParallel().ForAll(acc =>
{
lock (this)
++countTotal;
if (!string.IsNullOrEmpty(acc.isMapped))
{
lock (this)
++countMapped;
}
if (string.IsNullOrEmpty(acc.isMapped))
{
lock (this)
++countNotMapped;
}
if (acc.HasError || acc.NotUnique || acc.DefalutName || acc.DefaultValue)
{
lock (this)
{
++countError;
errorFound = true;
}
}
});
#endregion
}
我知道isMapped的两个条件可能仅在一个if-else中(这会影响锁吗?)
谢谢。锁将破坏并行获得的性能 可以使用联锁增量 你也不需要数到那么多。循环后,您可以计算一些:
countTotal = MyList.Count();
countNotMapped = countTotal - countMapped;
errorFound = errorCount > 0;
但无论你做什么,你都应该对此进行分析,即计时。您可以使用秒表类进行此操作。然后你可以尝试不同的方法,看看哪个更快
然后,您应该尝试以下方法:
countMapped = MyList.Count(acc => istring.IsNullOrEmpty(acc.isMapped);
countMapped = MyList.AsParallel().Count(acc => istring.IsNullOrEmpty(acc.isMapped);
你确定锁上计数器是必要的吗?当我没有使用它时,我得到了一些奇怪的结果。我找不到一个接近我关于锁的问题的答案。这不是答案,但我不能评论,因为声誉不好。如果您需要设置线程安全的计数器,请使用而不是锁定。不要
锁定(此)
,您不知道实例上还有什么可能被锁定。谢谢。我用4500个项目测试了三种方法:并行ForAll(获得860ms)“正常”计数430ms和“并行”计数800ms。最好的方法是只使用两个计数,并在循环结束时计算其他属性。
countMapped = MyList.Count(acc => istring.IsNullOrEmpty(acc.isMapped);
countMapped = MyList.AsParallel().Count(acc => istring.IsNullOrEmpty(acc.isMapped);