DIY Mods
DIY Mods

Reputation: 79

The most efficient way (performance/time wise) to find a highest value in a List with continuously changing values?

I have an app that uses performance counters to get the cores/threads load and finding the highest value. Since there are 12/16/36 etc. threads normally in our days, I used a List and Math.Max to find the highest load.

However, the refresh interval is 100ms, so it must make calculations 600 times per minute and I want to optimize the code as much as possible, to be able to go with the even faster refresh rate.

What is the most efficient way to do that? I read the THREAD about it where people tested the efficiency, and while some say there is nearly no difference between Math.Max and for/while/if implementation, others say that when you work with doubles or float (which is what I have), the difference is huge, 0.3465041 sec for inline implementation and 6 sec for Math.Max.

So, what will be the best way to do the calculations in your opinion and how it can be done with a List? Thank you in advance! Here is what I use ATM:

 private void maxThreadTimer_Tick(object sender, EventArgs e) //Max Thread Timer
    {
    float allCores1 = coreLoad1.NextValue();
    float allCores2 = coreLoad2.NextValue();
    float allCores3 = coreLoad3.NextValue();
    float allCores4 = coreLoad4.NextValue();
    float allCores5 = coreLoad5.NextValue();
    float allCores6 = coreLoad6.NextValue();
    float allCores7 = coreLoad7.NextValue();
    float allCores8 = coreLoad8.NextValue();
    float allCores9 = coreLoad9.NextValue();
    float allCores10 = coreLoad10.NextValue();
    float allCores11 = coreLoad11.NextValue();
    float allCores12 = coreLoad12.NextValue();
    float allCores13 = coreLoad13.NextValue();
    float allCores14 = coreLoad14.NextValue();
    float allCores15 = coreLoad15.NextValue();
    float allCores16 = coreLoad16.NextValue();

    List<float> valuesList = new List<float> { allCores1, allCores2, 
    allCores3, allCores4, allCores5, allCores6, allCores7, allCores8, 
    allCores9, allCores10, allCores11, allCores12, allCores13, allCores14, 
    allCores15, allCores16 };

    float tMax = valuesList.Max();
    }

Upvotes: 0

Views: 449

Answers (3)

Chaos
Chaos

Reputation: 269

Creating any collection just to perform a Max operation is going to be overhead you don't need, especially if you're not going to use the collection later. Make a local method that tracks the max as items are evaluated. This ends up being ~150ms over a million iterations:

private void maxThreadTimer_Tick(object sender, EventArgs e)
{
    float tMax = 0;
    void TrackMax(float value)
    {
        if (value > tMax)
            tMax = value;
    }

    TrackMax(coreLoad1.NextValue());
    TrackMax(coreLoad2.NextValue());
    // etc etc etc
}

Upvotes: 1

Matthew Watson
Matthew Watson

Reputation: 109567

I would have thought that the vast majority of the overhead was coming from the individual calls to coreLoadX.NextValue() and that any optimisations you make to the code that's trying to find the maximum value will have little noticeable effect.

Having said that, for the code you gave the most performant solution is likely to be:

float max = coreLoad1.NextValue();

float value = coreLoad2.NextValue();

if (value > max)
    max = value;

value = coreLoad3.NextValue();

if (value > max)
    max = value;

value = coreLoad4.NextValue();

if (value > max)
    max = value;

value = coreLoad5.NextValue();

if (value > max)
    max = value;

value = coreLoad6.NextValue();

if (value > max)
    max = value;

value = coreLoad7.NextValue();

if (value > max)
    max = value;

value = coreLoad8.NextValue();

if (value > max)
    max = value;

value = coreLoad9.NextValue();

if (value > max)
    max = value;

value = coreLoad10.NextValue();

if (value > max)
    max = value;

value = coreLoad11.NextValue();

if (value > max)
    max = value;

value = coreLoad12.NextValue();

if (value > max)
    max = value;

value = coreLoad13.NextValue();

if (value > max)
    max = value;

value = coreLoad14.NextValue();

if (value > max)
    max = value;

value = coreLoad15.NextValue();

if (value > max)
    max = value;

value = coreLoad16.NextValue();

if (value > max)
    max = value;

That's just your common-or-garden variety of "unroll the loop".

Upvotes: 2

Ricardo Peres
Ricardo Peres

Reputation: 14535

I think that what you need is a SortedSet<T>. This has several advantages:

  1. No duplicates
  2. Always sorted
  3. Generic, which means you can use any type
  4. You have the Max and Min properties

See more here: https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.sortedset-1.

Upvotes: 0

Related Questions