Copied to clipboard

Flag this post as spam?

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


  • Lee 1130 posts 3088 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 1130 posts 3088 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 2773 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 1130 posts 3088 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 1130 posts 3088 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 1130 posts 3088 karma points
    Jan 24, 2011 @ 07:55
    Lee
    0

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

  • Lee 1130 posts 3088 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 :)

Please Sign in or register to post replies

Write your reply to:

Draft