4
\$\begingroup\$
TA.ServiceProxy.RoleManagement.GetSubPrivilagesResponses subPrivilagesResponses = GetSubPrivilagesFromPrivilageCodeStatic("Authoring01");
if (subPrivilagesResponses != null && subPrivilagesResponses.SubprivilagesList != null)
{
    for (int j = 0; j < subPrivilagesResponses.SubprivilagesList.Length; j++)
    {
       if (subPrivilagesResponses.SubprivilagesList[j].PrivilageCode == "CREATOR")
       {
           objTemplate.IsTagged = true;
           break;
       }
    }
}

The above code is written as

TA.ServiceProxy.RoleManagement.GetSubPrivilagesResponses subPrivilagesResponses = GetSubPrivilagesFromPrivilageCodeStatic("Authoring01");
if (subPrivilagesResponses != null && subPrivilagesResponses.SubprivilagesList != null)
{
   var item = subPrivilagesResponses.SubprivilagesList.SingleOrDefault(cd => cd.PrivilageCode == "CREATOR");
    if(item != null && item.PrivilageCode == "CREATOR")
        objTemplate.IsTagged = true;                              
}

In what are the different way it can be modified in order to boost performance and efficiency by making use of Lambda or LINQ

\$\endgroup\$
3
  • 2
    \$\begingroup\$ The first version finds the first of possible more items having PrivilageCode == "CREATOR", while the second actually ensures that there is only one (or none) item having that predicate - if more items satisfy the condition a ThrowMoreThanOneMatchException exception is thrown. So they are not doing the exact same thing. Which one is the correct/preferred? \$\endgroup\$
    – user73941
    May 14, 2020 at 8:30
  • \$\begingroup\$ Good Catch. It will always be only one or none. Apart from SingleOrDefault. What are all possible ways to match PrivilageCode == "CREATOR". I mean to say how can the above snippet can be rewritten in different possible ways to yield the above condition. Even I or the readers would benefit a lot @HenrikHansen \$\endgroup\$ May 14, 2020 at 9:41
  • \$\begingroup\$ do you actually have any performance issue with the current code ? if yes, then please explain what is the issue, and where it happens. (include any code if any). \$\endgroup\$
    – iSR5
    May 14, 2020 at 17:06

3 Answers 3

5
\$\begingroup\$

Because the question is about performance and efficiency that's why some sort of benchmarking would be essential to compare different implementations. I have found BenckmarkDotNet really useful for these kind of experiments.

You can define the for loop version as your baseline and the tool will compare the other implementation against that. Here is my simplified example how to setup your environment for measurement:

[HtmlExporter]
[MemoryDiagnoser]
[SimpleJob(BenchmarkDotNet.Engines.RunStrategy.ColdStart, targetCount: 100)]
public class IterationOptimalizationExperiment
{
    private static List<Data> target;
    private const string TheOne = "TheOne";

    [GlobalSetup]
    public void Setup()
    {
        target = Enumerable.Range(0, 10000)
            .Select(i => new Data { Id = i, Type = i % 7777 == 0 ? TheOne : "NotTheOne" })
            .ToList();
    }

    [Benchmark(Baseline = true)]
    public void WithFor()
    {
        bool hasFound = false;
        for (int i = 0; i < target.Count; i++)
            if (string.Equals(target[i].Type, TheOne, StringComparison.OrdinalIgnoreCase))
            {
                hasFound = true;
                break;
            }

    }

    [Benchmark]
    public void WithForEach()
    {
        bool hasFound = false;
        foreach (var t in target)
            if (string.Equals(t.Type, TheOne, StringComparison.OrdinalIgnoreCase))
            {
                hasFound = true;
                break;
            }
    }

    [Benchmark]
    public void WithAny()
    {
        bool hasFound = target.Any(t => string.Equals(t.Type, TheOne, StringComparison.OrdinalIgnoreCase));
    }
}

And you should simply call the following command to start your experiment: BenchmarkRunner.Run<IterationOptimalizationExperiment>();

When you run it in Release mode it will dump something like this: enter image description here

\$\endgroup\$
3
\$\begingroup\$

If you're using C#6 or above, you can use the null conditional operator ?.:

var hasCreator = GetSubPrivilagesFromPrivilageCodeStatic("Authoring01")?.SubprivilagesList?.Any(cd => cd.PrivilageCode == "CREATOR") ?? false;
if (hasCreator) 
{
    objTemplate.IsTagged = true;
}

If it's not too late, I'd correct the spelling of privilege in your code. I misspelt latitude (as lattitude) in some key js once and frustrated my colleagues for years.

\$\endgroup\$
1
  • \$\begingroup\$ you could inline it with objTemplate.IsTagged directly. \$\endgroup\$
    – iSR5
    May 14, 2020 at 17:04
2
\$\begingroup\$

The only think that comes to my mind is to rewrite this:

var item = subPrivilagesResponses.SubprivilagesList.SingleOrDefault(cd => cd.PrivilageCode == "CREATOR");
    if(item != null && item.PrivilageCode == "CREATOR")
        objTemplate.IsTagged = true;    

into this:

if (subPrivilagesResponses.SubprivilagesList.Any(cd => cd.PrivilageCode == "CREATOR"))
        objTemplate.IsTagged = true;
\$\endgroup\$
1
  • 2
    \$\begingroup\$ You could set objTemplate.IsTagged to equal ...Any() directly instead of the if-statement. \$\endgroup\$
    – user73941
    May 14, 2020 at 8:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.