Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Lee 1123 posts 3059 karma points
    Jan 22, 2011 @ 10:22
    Lee
    0

    Linq2Umbraco Performance Help

    I have the following structure

    Category
      -- Topic
         -- Post

    Where a category can have multiple topics and each of those topics can have multiple posts, just like this forum. When I list the categories I am showing the last post within a category and came up with this method.

    Is there a better way of doing this? Obviously I am looking for as big a performance increases I can from any change

            public ForumPost GetLastPostInCategory(List<ForumTopic> topics)
            {
                // Get latest Post (Must be a more efficient way of doing this in linq!)
                var posts = new List<ForumPost>();
                foreach (var topic in topics)
                {
                    posts.AddRange(topic.ForumPosts);
                }
    
                // Setup local variables to use
                return lpost = posts.OrderByDescending(x => x.CreateDate).First();
            }

    Any advice/tips greatly appreciated.

  • Sascha Wolter 615 posts 1101 karma points
    Jan 22, 2011 @ 20:38
    Sascha Wolter
    0

    Hi Lee,

    I don't know the exact code but can't you do something along

    var posts = from p in [YourDataContext].ForumPosts

                     where p.CreateDate == [MAX(p.CreateDate)]      //don't know if that is possible here but would make it quite a lot better. Maybe it's worth even

                                                                                            //running an additional query beforehand just to get the latest date?

                     orderby p.CreateDate;

    if (posts.Count > 0) { posts = posts.First(); }

    ? Hth, Sascha

  • Lee 1123 posts 3059 karma points
    Jan 23, 2011 @ 09:15
    Lee
    0

    Thanks for the tips, I'll see what I can incorporate into it :)

  • Morten Christensen 596 posts 2770 karma points admin hq c-trib
    Jan 23, 2011 @ 21:29
    Morten Christensen
    2

    Hi Lee,

    This is an interesting "issue", and I have already sent you the link to a post by Jon Skeet about LINQ Performance:
    http://msmvps.com/blogs/jon_skeet/archive/2005/10/02/a-short-case-study-in-linq-efficiency.aspx

    I had been looking at it myself because I was in a similar situation where using "order" or "orderby" might have a performance implication due to the number of items in a list. So I have been doing some unit tests similar to the benchmarks in the post above, and the following method is the fastest (rewritten to match your sample  code):

            public ForumPost GetLastPostInCategory(List<Topic> topics)
    {
    ForumPost newestPost = topics[0].ForumPosts[0];//Assumes no empty lists
    foreach (var topic in topics)
    {
    foreach (var post in topic.ForumPosts)
    {
    if (post.CreateDate > newestPost.CreateDate)
    {
    newestPost = post;
    }
    }
    }

    return newestPost;
    }

    Result was 45ms with a list of 10.000 topics each containing 1000 posts. Best result using LINQ (and Extension method) was 67ms. I tried running your sample code as well, which gave a result of 5sec 12ms, so you are looking at quite a performance enhancement dropping the OrderBy - and no need to create a new list with all your forum posts if you are only going to return the latest post.

    - Morten

  • skiltz 501 posts 701 karma points
    Jan 23, 2011 @ 23:28
    skiltz
    0

    Morten thanks for posting this. Really helped me out.

     

  • Lee 1123 posts 3059 karma points
    Jan 24, 2011 @ 07:44
    Lee
    0

    Morton thanks for taking the time to look into this :)  Really appreciate it, and the results are just what I was looking for.  Only one issue I have though, when I try to do this I get the following error??

  • Lee 1123 posts 3059 karma points
    Jan 24, 2011 @ 07:47
    Lee
    0

    Ignore me, its early :P  Just sorted it with

    var newestPost = topics[0].ForumPosts.ToList()[0]
  • Lee 1123 posts 3059 karma points
    Jan 24, 2011 @ 07:55
    Lee
    0

    Morten out of interest what do you use for your Unit Tests?

  • Lee 1123 posts 3059 karma points
    Jan 24, 2011 @ 08:03
    Lee
    0

    Actually, while we are still on this subject :P  My next task is to find an efficient way of doing the same thing, but ordering the topics listing in a category by the latest post.  The code I currently have is this, which just uses the default sort order

                var maintopics = from t in u.ForumTopics
                                 where t.ParentNodeId == CurrentNode.Id
                                 orderby t.SortOrder descending 
                                 select t;

    But this isn't right, as if someone posts in the bottom topic I want it to be at the top not stay at the bottom - I'm going to have a play and post what I come up with back here... But if you have any suggestions I'd be happy to see/hear them :)

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies