1

My company is a bit concerned that there might be a performance difference between the following two ways of getting an appointment from Outlook:

private Microsoft.Office.Interop.Outlook.AppointmentItem FindeAppointment(DateTime startzeit, string subject)
{
    string filter = string.Format("[Start] = '{0}' AND [Subject] = '{1}' AND [BillingInformation] = 'TEST'", startzeit.ToShortDateString() + " " + startzeit.ToShortTimeString(), subject);
    MAPIFolder calendarFolder = outlookApplication.Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar);
    Items items = calendarFolder.Items;
    return items.Find(filter) as AppointmentItem;
}

private AppointmentItem FindeAppointment(DateTime startzeit, string subject)
{
    MAPIFolder calendarFolder = m_outlookApplication.Session.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
    IEnumerable<AppointmentItem> items = calendarFolder.Items.OfType<AppointmentItem>();
    return items.FirstOrDefault(p => p.Start == startzeit &&
                                        p.Subject == subject &&
                                        p.BillingInformation == "TEST");
}

We want to do it the LINQ way, because we had some issues with the filter lately, so we needed a workaround.

I dont know any good way testing the performance of these method, I don't want to create thousands of appointments.

So, anybody has some figures or can tell me what's faster or atleast, how to test it?

Or should we just not care what to use, because its a very low speed different?

user990423
  • 1,397
  • 2
  • 12
  • 32
Jannik
  • 2,310
  • 6
  • 32
  • 61
  • Check http://stackoverflow.com/questions/14032709/performance-of-find-vs-firstordefault, it suggest why Find is a better option – Mrinal Kamboj Oct 21 '15 at 13:13
  • Contd - In this case you are fetching a single element, but in case you would be working with multiple elements, then PLinq would tend to have an edge over standard Task based parallelization – Mrinal Kamboj Oct 21 '15 at 13:18
  • @MrinalKamboj That article is comparing `First` with `List.Find`, not `Outlook.Items.Find`. Outlook may have a very different implementation that takes advantage of indexing in Exchange. – D Stanley Oct 21 '15 at 13:59
  • @DStanley if we bring everything in memory and create a IEnumerable still the Find implementation seems to have an edge, but in this case, its possible that the Com interop do something similar to IQueryable, which surely have an advantage of not leading all data in memory and doing necessary filtering on the server – Mrinal Kamboj Oct 21 '15 at 14:13

2 Answers2

1

Using LINQ statements with OOM objects is not a really good idea. The fact is that underlying COM objects are left unreleased. If you do not release these objects in a timely manner, you can reach the limit imposed by Exchange on the maximum number of items opened at any one time. This is particularly important if your add-in attempts to enumerate more than 256 Outlook items in a collection that is stored on a Microsoft Exchange Server.

Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. Read more about that in the Systematically Releasing Objects article.

Also I have noticed that you use multiple dots in the single line of code:

outlookApplication.Session.GetDefaultFolder

The Session property of the Application class returns an instance of the Namespace class which should be released after. As you may see in such cases objects are left without a control when they are released. So, I alway recommend breaking the chain of property and method calls and declare them on separate lines of code.

Finally, the Find/FindNext or Restrict methods do not load items into the memory as LINQ does. So, they will be much faster. You can read more about these methods in the following articles:

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
0

This is conjecture, but I would not be surprised at all to discover that Outlook.Items.Find was fester because it does took advantage of indexing in Exchange rather than bringing all items into memory and iterating them via Linq.

how to test it?

The only way to know for sure it to get a representative sample for your environment and test searching both ways. If your production environment is not big yet, but you are "worried" that it may become big, that may mean creating "thousands of appointments" in a test Exchange environment. The good news is you already know how to use the API, so creating a bunch of random appointments should not be a big deal. :)

D Stanley
  • 149,601
  • 11
  • 178
  • 240