Alterian ACM : Are you having Alterian ACM Performance Issues ?

Recently, we were developing an Alterian ACM website.  When we went live with it, we had massive performance issues.  After weeks of searching and even getting an Alterian ‘consultant’ in for help, with no luck, I was eventually able to find the problem in the depths of the API.  When designing an Alterian site DO NOT design your content types with a high number of fields, aim to keep it to 10-15 and your life will be much easier.  If you have ever used .GetFieldValue() from the DataProvider the code behind it is horribly inefficient… so much so, that it was causing up to 10 second page load times from our site.

If you load up the BusinessLayerPrivder assembly in dotpeek and navigate to DataProvider -> GetFieldValue, you’ll see this code:

          foreach (ValidFieldDefValue validFieldDefValue in def.ValidFieldValues)
{
if (DataProvider.GetFieldType(def.FieldType) == typeof (int))
validValues.Add(new ValidValue()
{
IsDefault = validFieldDefValue.Default,
Value = (object) int.Parse(validFieldDefValue.Value, (IFormatProvider) CultureInfo.InvariantCulture),
ValueId = validFieldDefValue.ValueId,
Order = validFieldDefValue.OrderNumber
});
else
validValues.Add(new ValidValue()
{
IsDefault = validFieldDefValue.Default,
Value = (object) validFieldDefValue.Value,
ValueId = validFieldDefValue.ValueId,
Order = validFieldDefValue.OrderNumber
});
}

Can you spot the issue?…. On our project we had 7 different language variations with a requirement to dynamically add certain items into other parts of the site.  To make our content editors’ lives easier, we added all our language field variations within each of our content types, which sounded logical to us.  This design meant that the content editors only had to deal with one page in a single content tree to open up and change any language, add related items etc… We opted for this route as using the Alterian language translations ‘thing’ would have made managing close to impossible. We also needed different menu options, image variations etc… to cover the different placement scenarios, which is why we had over 40 fields in some content types.

The design of the site was very complex, which meant on some pages we needed to call up to 40 different items and this is where we hit our problem. When you call getFieldValue() it takes the item and then manually loops through every single field in that object until it finds a match and on the next call it does the same thing. If your content type has 40 fields and you want to get all of them using getFieldValue() ACM roughly could do 40*40 loops, or, 1600 iterations for one item !!!!

In our design we have 40 items on a page request so… 1600 * 40 items which meant, in theory, it could take nearly 64,000 loop iterations just to get the data we needed for one page (we still have other stuff to do with that data!).  When I discovered that gem, it was obvious why our site’s page load time was so shocking, even though Alterian had denied it was their API from the start.

We logged this issue with support but with no help, so, I had to find a work around.  Until it is fixed, this is the best approach I’ve found.  Instead of calling getFieldValue() it’s much more efficient to call CopyOfFieldsDetails() to get everything yourself and manually parse it.  In the example below I pass in a Dictionary<string, string> containing the name of the fields I want returned.  Doing this cuts our page load time down by 3 seconds minimum.

Note: AlterianRow is a custom object but can be replaced with a dictionary etc..

     var items = current.CopyOfFieldsDetails.Cast()
.Select(x => new AlterianRow { Key = x.FieldName, Value = x.FieldValue }).ToList();
var keys = dictionary.Keys.ToList();
foreach (var item in keys)
{
var defaultValue = items.Where(y => y.Key == (string.Format("{0}_{1}", item, Language.GBR.ToString()))).FirstOrDefault();
var value = string.Empty;
if (defaultValue != null)
{
value = defaultValue.Value;
items.Remove(defaultValue);
}
dictionary[item] = value;
}

Note: This does not work for links. It will only return an ILINK; you will either need to manually convert this (not sure how) or call getFieldValue() instead 🙁
Enjoy!

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

More Posts