基于属性迭代和设置计数器的快速方法

时间:2014-04-17 07:21:43

标签: c# loops parallel-processing

我想迭代一个具有一些典型属性的自定义类的List。 该列表将是巨大的并且正在增长(从3000项开始,可能达到+ 10k)

我正在阅读以非常快的方式迭代和检查属性的最佳方法,因为我将填写一些计数器。

In .NET, which loop runs faster, 'for' or 'foreach'?

http://www.codearsenal.net/2013/12/csharp-multithreading-loop-parallel-for.html#.U09-qPl_vA0

但如果我需要按照逻辑检查这些属性......什么会更快?

目前我的代码看起来像这样:

  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(这会影响锁吗?)

谢谢。

1 个答案:

答案 0 :(得分:2)

锁会杀死并行获得的性能。

您可以使用互锁增量http://msdn.microsoft.com/en-us/library/dd78zt0c(v=vs.110).aspx

Interlocked.Increment(countMapped)

此外,您不需要计算这么多东西。在循环之后,您可以计算一些:

countTotal = MyList.Count();
countNotMapped = countTotal - countMapped;
errorFound = errorCount > 0;

但无论你做什么,你都应该对此进行分析,即时间。您可以使用Stopwatch类。然后你可以尝试不同的东西,看看哪个更快。

然后你应该试试这些:

countMapped = MyList.Count(acc => istring.IsNullOrEmpty(acc.isMapped);

countMapped = MyList.AsParallel().Count(acc => istring.IsNullOrEmpty(acc.isMapped);