0

I have a method that contains nested parallel loops to populate one of the properties of the loop.

public static string CalculateFantasyPointsLeagueSettings(ref List<Projections> projection, League league, Teams teamList)
{
    string PPR = "";
    var stats = (from a in league.Settings.StatCategories.stats
                 join b in league.Settings.StatModifiers.stats on a.StatId equals b.StatId
                 select new Tuple<string, double>(a.Name.Replace(" ", string.Empty), b.Value)).ToList();


    var props = new Projections().GetType().GetProperties();

    double receptionValue = (stats.Where(a => a.Item1 == "Receptions").Select(a => a.Item2).FirstOrDefault());

    if (receptionValue == 1.0)
    {
        PPR = "PPR";
    }
    else if (receptionValue == .5)
    {
        PPR = "Half PPR";
    }
    Parallel.ForEach(projection, proj =>
    {
        double points = 0;
        Parallel.ForEach(props, prop =>
        {

            var stat = (from a in stats
                        where a.Item1 == prop.Name
                        select
                         Convert.ToDouble(prop.GetValue(proj, null)) * a.Item2
                        ).FirstOrDefault();

            points += stat;
        });
        proj.ProjectedPoints = Math.Round(points, 2);
        proj.FantasyTeam = (from a in teamList.TeamList
                            where a.Players.player.Select(b => b.Name.Full).Contains(proj.Name)
                            select a.Name).FirstOrDefault();
    });
    return PPR;
}

What this method does is calculates the points for a fantasy football player based on their league settings (stats object) and their projected stats (projections list). Since stats is not a static list (you can have custom settings), I need to be able to loop through all the items in that list, and calculate each one by hand. In order to do this, I have to get the property in Reflection and than use it's value. Since projection has about 35k records and stats will be well over 30, this method takes a long time to run, probably due to reflection. I am trying to figure out if there is anything I can do to make it run faster. Right now it takes about 2-3 seconds, which is not ideal. I cannot put it in cache as it is fairly dynamic. Any help would be greatly appreciated.

Thomas Ayoub
  • 29,063
  • 15
  • 95
  • 142
Isaac Levin
  • 2,809
  • 9
  • 49
  • 88
  • 5
    Why are you using reflection? Instead of properties why not use a `Dictionary`? – juharr Oct 05 '16 at 12:29
  • 3
    Generally, reflection should be the last thing you go to - it's slow and you lose the benefits of a strongly typed language. This code would be great to refactor into a common design pattern. Have you read up on the [Decorator Pattern](http://stackoverflow.com/questions/2707401/please-help-me-understand-the-decorator-pattern-with-a-real-world-example)? – Jonesopolis Oct 05 '16 at 12:29
  • In general i would advice to have alook at the TPL DataFlow to get better control of the worlflows – Boas Enkler Oct 05 '16 at 12:31
  • @Thorarins The use of `Tuple` results in no boxing and there is no casting either. – juharr Oct 05 '16 at 12:32
  • @Thorarins The convert is not done on the values in the `Tuple`. – juharr Oct 05 '16 at 13:03
  • @juharr, without reflection, how do i get the value of stats based on proj? Even if I use a dictionary, I am still going to have to get values – Isaac Levin Oct 05 '16 at 15:12
  • That I cannot tell you since I don't know where your list of `Projections` comes from, but you'd just need to change it to populate a dictionary instead of properties. – juharr Oct 05 '16 at 16:34
  • Projections comes from a DB table. I have a DTO that has the same schema as the DB and populate that with value injection. So each stat is a column – Isaac Levin Oct 06 '16 at 01:04

0 Answers0