Fast way to iterate and set counters based on prop

2019-09-06 02:01发布

I would like to iterate through a List of a custom class with some typical properties. The list will be huge and growing(starts with 3000items and may reach +10k)

I am reading about best ways to iterate in a very fast way and checking properties, because I shall fill some counters.

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

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

But if I need to follow a logic checking these properties... what would be faster?

At the moment my code looks like this:

  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
  }

I know two of the conditions for isMapped could be in just one if-else(Might this affect the lock?)

Thank you.

1条回答
The star\"
2楼-- · 2019-09-06 02:33

The locks will kill the performance gained from parallel.

You can use interlocked increment http://msdn.microsoft.com/en-us/library/dd78zt0c(v=vs.110).aspx

Interlocked.Increment(countMapped)

Also you don't need to count so many things. After the loop you can calculate some:

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

But whatever you do you should profile this, i.e. Time it. You can use Stopwatch class for this. Then you can try different things to see which is faster.

You should then try these:

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

countMapped = MyList.AsParallel().Count(acc => istring.IsNullOrEmpty(acc.isMapped);
查看更多
登录 后发表回答