Containers only exists in X++ – you’ll not find a similar generic construct elsewhere. They serve many purposes like storage of blob data (like images), transferring of large portions of data, building hierarchical in-memory data structures, serializing objects, returning multiple values from methods – to just name a few common use cases.
For the past few years I’ve had the impression that container’s performance was poor. I guess it comes from the R3 days when I wrote the Pedal to the metal blog. This R3 blog deals with how to write X++ code that is fully managed – as everything else requires slow interop calls.
Code like this would raise my eyebrows:
Why call conlen() for each iteration – it is not changing? I decided to find the overhead of calling conlen(), I assumed it would be significant due to an interop call.
A small test revealed that my dev VM could do a staggering 150 million calls to conlen() per second. In comparison I could “only” do 24 million calls to a private method. With these speeds, clearly there were no expensive interop calls. What was going on?
.NET reflector revealed that an X++ container is a System.Object. conlen() is just returning the value of the System.Object.Length property, and conpeek is simply indexing the array System.Object.GetValue(index). No interop required.
X++ container is a System.Object
Some usages of containers will result in interop calls – for example when serializing and deserializing. But many common case scenarios will not. Kudos to the X++ compiler team for this improvement. I can take my eyebrows down again – and I’ll not spend another breathe worrying about container performance.