[USPC] Ultimate Sitecore Performance Championship: GetChildren() vs Axes.GetDescendants()

I’m that kind of guy who is always asking himself if this given method has a better performance than that other one, even if I know that it doesn’t make any real difference in 97.4% of the cases. It’s almost like a national sport on Santos’s house.

I was surprised and shocked when I realized that there aren’t a lot of articles/posts on the Sitecore blogosphere about performances battles. That’s why I decided it was time to convert those personal benchmarks into useful public material.

Ladies and gentlemen, that’s how the USPC was born.


USPC – Fight 1

And nothing better to start this blog series than the most simple methods battle possible. The one that every single Sitecore developer will use multiple times in their careers. Yes, ladies and gentlemen, I’m talking about getting the current Item children. For the records, I used a Sitecore 8.2 as an arena.

On The Red Corner… Item.GetChildren()

This is possibly the very first method every one of us learned when having the first contact with Sitecore. It’s without a doubt the most simple way of navigating through item’s children because it’s totally intuitive. You get the item’s instance, type .get and let the autocomplete do its magic. The .GetChildren() will be there, just waiting to be used.


On The Blue Corner… Item.Axes.GetDescendants()

This second option is for sure less known, but if your goal is to get all the children including multiple levels of navigation, it only takes one line of code. Anyway, it uses two dots so it must be more complicated, right? That’s what we will see.


Are You Ready? Let’s Get It On!

So in order to be able to benchmark those big boys, we need to define a fair scenario. In today’s fight, it’s going to be “What is the fastest way of getting all the children from a given item, including multiple levels descendants?”.

More precisely, fetch 2020 descendants items organized in the following way:

Root Item
    - SubItems 1
        - SubItems 1.1        
        (100 items)     
    (100 items)
    - SubItems 2.1
        - SubItems 2.1        
        (100 items) 
    (100 items) 
    - Bulk Items 10
        - Bulk Items 10.1       
        (100 items)     
    (100 items)

Each fighter will be executed multiple times and the average execution time will be used to determine the winner tonight.

The GetChildren() Fight Strategy

Since this method won’t fetch all levels of descendants by default, we need to define a strategy to do so, otherwise, it would be an easy victory to GetDescendants().

Let’s use simple tail recursion.

IEnumerable<Item> kids = FetchAllChildrenItems(Database.GetItem(rootItemId)).ToList();

private IEnumerable<Item> FetchAllChildrenItems(Item p_Item, bool p_ReturnRootItem = false)
    if (p_ReturnRootItem) {
        yield return p_Item;

    foreach (Item child in p_Item.GetChildren(ChildListOptions.SkipSorting))
        foreach (Item subChild in FetchAllChildrenItems(child, true)) {
            yield return subChild;

The GetDescendants() Fight Strategy

Not a big deal for him, this method already pulls all children from all levels by default. It will play it safe and do nothing else.

IEnumerable<Item> kids = Database.GetItem(rootItemId).Axes.GetDescendants().ToList();

The Judges Final Decision

The first execution batch was pretty simple. All the 2020 items were cached and the code was called as part of the HttpRequestBegin pipeline. And those are the final results in milliseconds:

1. GetDescendants():
    Average: 25.5615
 2. GetChildren() - Recursive:
    Average: 18.5540

Easy victory to GetChildren()!


But what about running those on a fresh Sitecore instance with no cache at all? I executed an iisreset before each running and those were the results:

1. GetDescendants():
    Average: 3322.1754
 2. Children - Recursive:
    Average: 2432.6024

Again, victory to the contender on the red corner.



It was pretty close, but the Item.GetChildren() may be faster

It’s all because it is more flexible. You can, for instance, pass the ChildListOptions.SkipSorting option which is responsible for a huge performance gain.


That means that depending on your requisites (when sorting matters), it may be better to just go ahead and use the one-liner solution. Less code is usually better.

Please note that the project with the complete solution is on my GitHub as a public repository. Fell free to play with it if you want.



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s