Abd
Abd

Reputation: 426

C# loop optimization

i have this loop and it loops for large count like 30 000 times at least
i am looking for some way to improve it's performance
DbRecordDictionary is derived from DictionaryBase class
here is the loop:

ArrayList noEnter = new ArrayList();
DbRecordDictionary oldArray = new DbRecordDictionary();
DbRecordDictionary userArray = new DbRecordDictionary();
DbRecordDictionary result = null;
foreach (string key in keys)
{
    if (noEnter.Contains(key))
    { //may need cast!
        if (count < 1)
            result.Add(key, userArray[key]);
        else if (oldArray.Count == 0)
            break;
        else if (oldArray.Contains(key))
            result.Add(key, userArray[key]);
    }                
}

Upvotes: 1

Views: 1520

Answers (5)

Peter
Peter

Reputation: 38485

Small small optimization could be using generics ArrayList noEnter = new ArrayList(); would be List noEnter = new List(); and DbRecordDictionary would inherit Dictonary instead of DictionaryBase.

im not 100% sure that you would gain performance but you will use a more modern c# style.

Upvotes: 0

Dean Chalk
Dean Chalk

Reputation: 20461

try this

(from k in keys
     where noEnter.Contains(k) &&
           oldArray.Count > 0 &&
           count < 1 &&
           oldArray.Contains(k)
     select k)
        .ToList()
        .ForEach(k => result.Add(k, userArray[k]));

Upvotes: 0

Ian Ringrose
Ian Ringrose

Reputation: 51917

If noEnter has more then about 10 items in it, then use a Dictionary rathern then a List/Array for it. As a Dictionary can look up a item without having to look at all the items, when an List/Array has to loop over all items.

Otherwise consider shorting "keys" and "oldArray" and then proforming a "merge" on them. Look at the code for a "merge sort" to see how to do the merge. (This would need carefull profiling)

Upvotes: 1

Guffa
Guffa

Reputation: 700372

From what I can see, the variable count or the oldArray never changes during the loop, so you can place those condition outside the loop, and make two different loops.

if (count < 1) {
  foreach (string key in keys) {
    if (noEnter.Contains(key)) {
      result.Add(key, userArray[key]);
    }
  }
} else if (oldArray.Count == 0) {
  // no data
} else {
  foreach (string key in keys) {
    if (noEnter.Contains(key)) {
      if (oldArray.Contains(key)) {
        result.Add(key, userArray[key]);
      }
    }                
  }
}

The collections noEnter and oldArray should be dictionaries, otherwise you will be spending a lot of execution time in the Contains calls.

Upvotes: 1

leppie
leppie

Reputation: 117250

You may want to use a Dictionary/Hashset for oldArray, but else there is not much you can do. Also noEnter if that is an array.

Upvotes: 2

Related Questions