Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

High Performance Multiplication/Evaluation in C#

Sorry for the vague thread title; hard to succinctly describe my question.

I have a collection of a large number of objects (couple thousand), defined as...

public class Item
{
    public int ID;
    public float A;
    public float B;
    public float C;
    public float D;
    public float E;
    public float F;
    public float G;
}

If I'm given a multiplier for each one of those float fields, what's the fastest way to find which Item in my large collection has the largest total of those floats multiplied by their multiplier.

For example, I've currently got something like...

public Item FindLargest(float aMult, float bMult, float cMult, float dMult, float eMult, float fMult, float gMult)
{
    Item largest = null;
    float largestTotal = 0f;
    foreach(Item item in ItemsCollection)
    {
        float total = item.A * aMult + 
                      item.B * bMult + 
                      item.C * cMult + 
                      item.D * dMult + 
                      item.E * eMult + 
                      item.F * fMult + 
                      item.G * gMult;
        if (total > largestTotal)
        {
            largest = item;
            largestTotal = total;
        }
    }
    return largest;
}

The performance of this is lacking, and so I'm wondering if there's anything I can do to restructure the data in such a way, ahead of time, so that the FindLargest call is much much faster. I've been doing it like this for a while, and performance was fine, with ~40-50 items in the ItemsCollection, but now the design of a different part of my application has changed, and as a byproduct, I need to process much larger set of data (~2000ish instead of ~50ish), so I'm interested in optimizing this further. Thanks for any help anyone can offer!

EDIT: I should have mentioned this to start with: I'm already parallelizing this in that what's calling this is already heavily parallelized. And what's calling this is indeed calling it many times, with many different parameters, very quickly. Every time a value changes in the open document in my app, this needs to be called about a hundred times, and it should feel 'responsive' (already doing all the calculations on multiple background threads, so I don't mean UI lockup).

EDIT 2: See my comments in the accepted answer.

like image 949
Chadd Nervig Avatar asked May 07 '26 18:05

Chadd Nervig


2 Answers

I don't think the problem is with your function here. I'm taking way less than 0.1 seconds to complete the function with 500,000 items in the collection.

You might want to find a way to optimize the part of the code that calls this function. Using PLINQ at that level should yield better results.

like image 127
Fun Mun Pieng Avatar answered May 10 '26 22:05

Fun Mun Pieng


One option is using PLINQ to make use of multiple cores.

        var result = (from item in ItemsCollection
                      let total = item.A * aMult + 
                                  item.B * bMult + 
                                  item.C * cMult + 
                                  item.D * dMult + 
                                  item.E * eMult + 
                                  item.F * fMult + 
                                  item.G * gMult
                      select new {item, total}).AsParallel().Max(i => i.total);
like image 40
Steven Jeuris Avatar answered May 10 '26 20:05

Steven Jeuris



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!