Why one loop is performing better than other memory wise as well as performance wise?

Posted by Mohit on Stack Overflow See other posts from Stack Overflow or by Mohit
Published on 2012-07-01T05:22:20Z Indexed on 2012/07/01 15:16 UTC
Read the original article Hit count: 182

Filed under:
|
|

I have following two loops in C#, and I am running these loops for a collection with 10,000 records being downloaded with paging using "yield return"

First

foreach(var k in collection) {
  repo.Save(k);
}

Second

 var collectionEnum = collection.GetEnumerator();
 while (collectionEnum.MoveNext()) {
   var k = collectionEnum.Current;
   repo.Save(k);
   k = null;
 }

Seems like that the second loop consumes less memory and it faster than the first loop. Memory I understand may be because of k being set to null(Even though I am not sure). But how come it is faster than for each.

Following is the actual code

  [Test]
    public void BechmarkForEach_Test() {
        bool isFirstTimeSync = true;
        Func<Contact, bool> afterProcessing = contactItem => {
            return true;
        };

        var contactService = CreateSerivce("/administrator/components/com_civicrm");
        var contactRepo = new ContactRepository(new Mock<ILogger>().Object);
        contactRepo.Drop();
        contactRepo = new ContactRepository(new Mock<ILogger>().Object);

        Profile("For Each Profiling",1,()=>{
            var localenumertaor=contactService.Download();
            foreach (var item in localenumertaor) {

            if (isFirstTimeSync)
                item.StateFlag = 1;

            item.ClientTimeStamp = DateTime.UtcNow;

            if (item.StateFlag == 1)
                contactRepo.Insert(item);
            else
                contactRepo.Update(item);

            afterProcessing(item);


        }
        contactRepo.DeleteAll();
        });

    }


    [Test]
    public void BechmarkWhile_Test() {
        bool isFirstTimeSync = true;
        Func<Contact, bool> afterProcessing = contactItem => {
                                                                 return true;
        };

        var contactService = CreateSerivce("/administrator/components/com_civicrm");
        var contactRepo = new ContactRepository(new Mock<ILogger>().Object);
        contactRepo.Drop();
        contactRepo = new ContactRepository(new Mock<ILogger>().Object);

        var itemsCollection = contactService.Download().GetEnumerator();

        Profile("While Profiling", 1, () =>
            {
                while (itemsCollection.MoveNext()) {

                    var item = itemsCollection.Current;
                    //if First time sync then ignore and overwrite the stateflag
                    if (isFirstTimeSync)
                        item.StateFlag = 1;

                    item.ClientTimeStamp = DateTime.UtcNow;

                    if (item.StateFlag == 1)
                        contactRepo.Insert(item);
                    else
                        contactRepo.Update(item);

                    afterProcessing(item);

                    item = null;
                }
                contactRepo.DeleteAll();

            });
    }

    static void Profile(string description, int iterations, Action func) {

        // clean up
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();

        // warm up 
        func();

        var watch = Stopwatch.StartNew();
        for (int i = 0; i < iterations; i++) {
            func();
        }
        watch.Stop();
        Console.Write(description);
        Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
    }

I m using the micro bench marking, from a stackoverflow question itself benchmarking-small-code

The time taken is

  • For Each Profiling Time Elapsed 5249 ms
  • While Profiling Time Elapsed 116 ms

© Stack Overflow or respective owner

Related posts about c#

Related posts about Performance