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:
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:
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,
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.
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;
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;
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
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)!
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.