Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace nested foreach to Increase performance

I have the following code which take longer time to execute. Is there any alternative that I can replace below code with LINQ or any other way to increase the performance?

var usedLists = new HashSet<long>();

foreach (var test in Tests)
{
    var requiredLists = this.GetLists(test.test, selectedTag);

    foreach (var List in requiredLists)
    {   
        if (!usedLists.Contains(List.Id))
        {
            usedLists.Add(List.Id);
            var toRecipients = List.RecepientsTo;
            var ccRecipients = List.RecipientsCC;
            var bccRecipients = List.RecipientsBCC;
            var replyTo = new List<string>() { List.ReplyTo };
            var mailMode = isPreviewMode ? MailMode.Display : MailMode.Drafts;
            OutlookModel.Instance.CreateEmail(toRecipients, ccRecipients, bccRecipients, this.Draft, mailMode, replyTo);
        }
    }
}
like image 329
user1494438 Avatar asked May 08 '26 13:05

user1494438


2 Answers

What do you actually do? Looking at

foreach (var test in Tests)
{
    var requiredLists = this.GetLists(test.test, selectedTag);
    foreach (var List in requiredLists)
    {   
        if (!usedLists.Contains(List.Id))

it looks to me that you try to get unique "List"s (with all those "var" I cannot tell the actual type). So you actually could replace that with a new function (to be written by you) and do

var uniqueLists = this.GetUniqueLists(Tests, selectedTag);

and finally call

this.Sendmails(uniqueLists);

which would iterate thru that list and send the mails.

If that could speed up the code or not, depends severely on the underlying GetLists / GetUniqueLists functions.

But in any case, it would make a great progress to your code: it becomes readable and testable.

like image 192
Bernhard Hiller Avatar answered May 10 '26 02:05

Bernhard Hiller


Assuming the result from GetList is large/slow enough in comparison to CreateEmail call, skipping your contains-add hashset comparison will speed things up. Try a call to Distinct([Your ListComparer]) or GroupBy():

var requiredLists = 
    Tests.SelectMany(test => this.GetLists(test.test, selectedTag))
         .Distinct([Your ListComparer]);
// or 
var requiredLists = 
    Tests.SelectMany(test => this.GetLists(test.test, selectedTag))
         .GroupBy(x => x.Id).SelectMany(x => x.First());

foreach (var List in requiredLists)
{   
    // (...)
    OutlookModel.Instance.CreateEmail(toRecipients, ccRecipients, bccRecipients, this.Draft, mailMode, replyTo);
}

You could also try PLINQ to speed up things but I think you might run into trouble with the CreateEmail call, as it's probably a COM object, so multithreading will be a hassle. If GetList is slow enough to be worth the multithread overhead, you may experiment with it in the first call when creating requiredLists.

like image 33
Tewr Avatar answered May 10 '26 02:05

Tewr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!