Skip to main content

.GetItems() Slower than .GetListItems() - Is It Not?

An old-school Tridion best practice says "whenever possible try to use GetListItems over GetItems due to significant performance degradation on the latter". Now that might have been very well possible on the old TOM (Tridion Object Model). But is it still the case with TOM.NET? Let's see...

In my previous three posts, I have been playing with several ways of generating navigation XML based on Structure Groups and Pages:
  • Generate Structure Group Navigation - GetItems TBB - gets all SGs and Pages in one call to .GetItems() using a filter with Recursive=true. It then iterates the list of objects and creates an XML document using the hierarchy given by the items' OrganizationalItem property;
  • Generate Structure Group Navigation - Reorder TBB - gets all SGs and Pages in one call to .GetListItems() using a filter with Recursive=true. It then iterates the flat XML, instantiates SG and Page objects using the Engine.GetObject() method, and uses the .OrganizationalItem property to reorder the XML nodes into a hierarchical structure that matches the SG/Page nesting;
  • Generate Structure Group Navigation - Recursive TBB - gets SGs and Pages directly under the current Structure Group by making a call to .GetListItems() using a filter with Recursive=false. For each child SG, it calls itself recursively, and adds the returned items to their direct parent;
So the question is - which approach performs the best?

I conducted the tests on a Tridion 2013 GA instance that had 221 Structure Groups and 2173 Pages, running on my VMWare image on Windows Server 2008 R2 Standard, 4GB RAM, dual core 2.40GHz.

The results were surprising, at least to me:
  • GetItems TBB - 45 seconds;
  • Reorder TBB - 45 seconds;
  • Recursive TBB - 43 seconds;
I was expecting to see the Reorder TBB and Recursive TBB (using .GetListItems) clock significant lower execution time than GetItems TBB (using .GetItems).

And in fairness, it does clock significantly lower, if we strictly look at the execution of .GetListItems vs .GetItems (Reorder TBB executes .GetListItems in ~1 second vs 44 seconds it takes GetItems TBB to retrieve the objects).

However, Reorder TBB and Recursive TBB have to instantiate the actual SG and Page objects, because the XML returned by .GetListItems doesn't contain enough information to generate the navigation XML (i.e. it's missing URL and potentially other metadata). There is also some overhead in creating the hierarchical structure (iterating over nodes, appending them to different parents, removing unused nodes, etc). This is why in the end, the Recursive TBB is the fastest, because it doesn't have to restructure the retrieved XML. Instead, it constructs it as it is searching.

This makes the total execution time almost the same. In other words,
T(.GetListItems) + T(Engine.GetObject for each SG/Page) = T(.GetItems)

So to conclude -- yes, .GetListItems is significantly faster than .GetItems and whenever possible, by all means do use it. In my case, I actually needed the SG/Page objects, so I had to instantiate them. This is really where the time is consumed ultimately.


Comments

Rick said…
Note that in recent versions of SDL Tridion (2011 SP1 and higher), the TOM.NET partially pre-loads the objects returned by .GetItems. That means that all data you get out of .GetListItems will be mapped to the associated properties in the TOM.NET object. Accessing these pre-loaded TOM.NET object properties is cheap; it won't cause the object to be fully loaded. Only when you access a property which is not pre-loaded (not part of the list data) will a full load occur.
As long as you only access pre-loaded properties, using .GetItems will even be faster than .GetListItems (which has to build list XML based on those same pre-loaded data)!
Mihai Cădariu said…
Good comment, thanks Rick!

I noticed the call to .GetItems() is also very fast (~1s), but then iterating over the results and accessing their properties is where time is spent -- in line with what you're saying.