Friday, April 12, 2013

Compare AX X++ conIns function vs += for container insert

Below is a proof of concept (POC) comparing the 'conIns' function to the '+=' function for inserting records into a container. I know there are a few variables which would make this test not 100% but for a simple POC, this works great to illustrate my point. I made sure to intersperse the two functions between each other to counteract any kind of system load which could possibly kick in which would skew the data.

Use conIns when you need to insert data into a very specific part of the container (e.g. not at the end). If inserting at the end, just use +=.

Note: If you choose to do this on your own, make sure you don't have any breakpoints in or it will screw with the ticks and times will be off thus invalid results.

Results:
Looking at the infolog in Figure 1 below, it took ~2.35 seconds to insert 14,677 records using 'conIns' while it took ~1.67 seconds using '+='.  I've highlighted the outliers in the data that don't seem to conform to any pattern so I believe those were affected by some other process.

From: MSDN: Containers [AX 2012] 

Performance of containers

A container is best suited for processes that do not involve excessive modification to the size or contents of the container. When a container undergoes excessive additions of data, overall system performance can be decreased by the need to repeatedly copy container data and allocate new space.

+= is Faster Than conIns

When you want to build a new container by appending new data, you can use either the += operator or the conIns function. The += operator is the faster alternative. Use the conIns function only when you want to add new data before the last index of the original data.

static void daxTestConInsSpeed(Args _args)
{
    int         i;
    int         j;
    int         tickBegin; 
    int         tickEnd;
    int         totalTicks;
    int         runTestQty = 10;   
    CustTrans   custTrans;
    container   custTransCont;        
    str         conInsertMethod;
    
    for (j=1; j <= runTestQty; j++)
    {       
        // Grab the current 'tick' count in AX
        tickBegin = WinAPIServer::getTickCount();

        // delete the elements in the container
        custTransCont = conDel(custTransCont, 1, i);
        
        // reset the record counter
        i = 0;
        
        // Build the container with data depending on the function we are testing                                
        while select RecId from custTrans           
        {                        
            i++;
            
            if (j mod 2)
            {
                conInsertMethod = '+=';
                custTransCont += custTrans.RecId;
            }
            else
            {
                conInsertMethod = 'conIns';
                custTransCont = conIns(custTransCont, i, custTrans.RecId);
            }                
        }        
    
        // Grab the current 'tick' count
        tickEnd = WinAPIServer::getTickCount();
    
        totalTicks = tickEnd - tickBegin;
        
        info (strFmt("%1 took %2 seconds to process and insert %3 records", conInsertMethod, totalTicks/1000, conLen(custTransCont)));
    }
}

Figure 1 - The infolog from running the code above with highlighted outliers





No comments:

Post a Comment