web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Microsoft Dynamics AX (Archived)

Strange inconsistency between servers: performance of x++ and IL execution

(0) ShareShare
ReportReport
Posted on by

Hello,

This weekend I was flabbergasted after a long debugging run. There were performance issues (tell me something new) but this time it was actually interesting and not DB Related. Our un-optimized test environment loaded with a database copy of production was outperforming production by a factor 3 in a certain scenario. Hence the start of my research. And here it was that  found the following:

We have 2 production AOS's. One runs batches/connectors and one is for the regular AX clients. I have developed a small class/method which is called by the business connector (or WCF.. but that is generally much slower). The method can be called from X++, or from IL (static runClassMethodIL wrapper on the same method).

Some results (miliseconds). These results are always the same and consistent when ran in a loop.

PROD-1 PROD-2
Business connector X++ 150 80
Business connector IL 80 220
AOT-job with equal database requests 25 25

 

As you can see, one server runs fast in IL, and the other prefers X++. The results are the same when I run the method from an AOT-job. Obviously this is a situation that is 1) strange, 2) unwanted and 3) impossible to optimize against. So I would like to understand what is happening and possibly get them the same.

Some background on the environment:

AX 2012 R2 CU6

Both servers have 100% equal hardware and are dedicated machines (not virtual)

Both servers have the same AX installation (did a binary compare to verify this)

Both servers have the same latency and connectivity to the database (as can be seen from the 'AOT-job with equal database requests'.

Both servers are treated equally during model deployments when it comes to cleanup etc. full AOT and CIL compile is done before deployment.

Does anyone have an idea or suggestions of which direction I should be looking into? Note that I am not looking to optimize the method in question, but I want to understand and possibly fix the inconsistency between these two servers.

Any help is appreciated!

*This post is locked for comments

I have the same question (0)
  • Martin Dráb Profile Picture
    237,880 Most Valuable Professional on at

    Can you also measure the same methods executed by Business Connector from inside AX, instead of just running a job with the same DB requests?

    Where are you measuring time? Inside the methods or in the caller code (on client)?

  • Community Member Profile Picture
    on at

    test-job:

    static void Job1(Args _args) { str req=@"some string here"; str res; int64 s,e; s = WinAPI::getTickCount64(); res = MyClass::InvokeStatic(req); e = WinAPI::getTickCount64(); info(strFmt("duration: %1",e-s)); info(res); }

    class method:
    public str MyClass::InvokeStatic(str _args) 
    {
        return MyClass::construct().Invoke(_args);
    }
    public static server MyClass construct()
    {
        return new MyClass();
    }


    Timing Prod-1: 170ms

    Timing Prod-2: 80ms

    The IL variant is the same except instead I call MyClass::InvokeStaticIL(req) which is a container wrapper which does the same as InvokeStatic(str _args) except with a container argument.

    public server static str MyClass::InvokeStaticIl(str request)
    {
        str response;
    
        new XppILExecutePermission().assert();
    
        [response] = runClassMethodIL(classStr(MyClass),"InvokeIl",[request]);
    
        return response;
    }
    private server static container  InvokeIl(container args)
    {
        str request = conPeek(args,1);
        str response;
    
        response = MyClass::construct().Invoke(request);
    
        return [response];
    }


    Timing Prod-1: 90ms

    Timing Prod-2: 400ms

  • Community Member Profile Picture
    on at

    sorry, the MyClass::InvokeStatic has a "static server" signature.

  • Martin Dráb Profile Picture
    237,880 Most Valuable Professional on at

    Aha, so you do the measurement in AX client. I assume you call InvokeStaticIl() and InvokeIl through a .NET application + Business Connector and you have some other code measuring time, which you didn't show to us.

    Are you running the other application from the same machine as the AX connector? Because you measure time of the whole call, the most time may be taken by client/server latency and setting up BC connection. The function itself might still take the same time. This is what you should test be measuring the execution time inside the method.

  • Community Member Profile Picture
    on at

    I measure both through the AX client (above jobs) and using the .net application (full round trip). The above is a reponse to "Can you also measure the same methods executed by Business Connector from inside AX"

    The timing through the business connector are done using a warmed up connection. I first call the method but dont measure(this can be up to seconds because of connecting etc), and then call it again and measure 10/100 times. the timings are quite stable with each request.

    the business connector code can be summed up as:

    Axapta axClient;
    
    connect() {
    axClient.Logon(null, null, null, ConfigurationFilePath);
    }
    
    string invoke(request) {
    var ret = axClient.CallStaticClassMethod("MyClass", invokeMethod, request) as string;
    return ret;
    }
    
    with invokeMethod being either 'InvokeStatic' or 'InvokeStaticIl'
    
    

    The invoke returns data that contains internal AX timings (start of invoke + end of invoke date/time utc stamp). This is what i measure. The round tripping of the BC is not included in that, and does not seem to be of influence in this issue.

    Some timings when using the BC:

    Prod-2 static

    Dynamics AX = 78
    Dynamics AX = 78
    Dynamics AX = 80
    Dynamics AX = 93
    Dynamics AX = 114
    Dynamics AX = 93
    Dynamics AX = 93
    Dynamics AX = 93
    Dynamics AX = 109
    Dynamics AX = 93

    Prod-2 static IL

    Dynamics AX = 265
    Dynamics AX = 234
    Dynamics AX = 281
    Dynamics AX = 250
    Dynamics AX = 265
    Dynamics AX = 236
    Dynamics AX = 281
    Dynamics AX = 265
    Dynamics AX = 256
    Dynamics AX = 234

    Prod-1 Static

    Dynamics AX = 126
    Dynamics AX = 142
    Dynamics AX = 140
    Dynamics AX = 156
    Dynamics AX = 140
    Dynamics AX = 140
    Dynamics AX = 156
    Dynamics AX = 156
    Dynamics AX = 140
    Dynamics AX = 142

    Prod-1 static IL:

    Dynamics AX = 78
    Dynamics AX = 78
    Dynamics AX = 93
    Dynamics AX = 125
    Dynamics AX = 62
    Dynamics AX = 78
    Dynamics AX = 81
    Dynamics AX = 78
    Dynamics AX = 141
    Dynamics AX = 100

    As you can see the timings are different when called from AX client or from BS, but both times are start/end of the invoke method INSIDE AX, and do not include AX/BC roundtrip times (for the request at least).

    This might well be because of server/client switching or something similar. However, this would not explain why prod-1 and prod-2 behave so differently. 

  • Community Member Profile Picture
    on at

    Did a test without DB interaction. A simple PING/PONG scheme to avoid DB interference

    Tested through application/business connector only. 100 calls and timing is before/after total loop.

    PROD-1 PROD-2
    X++ 338ms 200ms
    IL 122ms 1000ms

    It shows the same pattern. Prod-1 likes IL, prod-2 likes x++

  • Martin Dráb Profile Picture
    237,880 Most Valuable Professional on at

    You said that "times are start/end of the invoke method INSIDE AX, and do not include AX/BC roundtrip times". And now you seem to be saying that the method doesn't contain any long-running code ("a simple PING/PONG scheme"), but this code still takes 122-1000 ms to execute.

    One of these statements seems to be wrong and I suspect it's the first one, because the job you showed wasn't measuring inside the method and it did include the client/server roundtrip. I suspect it's the case with your BC call too.

  • Community Member Profile Picture
    on at

    Both are correct. However:

    The first measurements which had actual content in the response and took 80ms+ were using the ax-timings (start/end).

    So: BC => AX => invoke method { register start; do-code; register end. Return start + end} read response start/end and use as measure.

    Since the timings of 0ms in the AX code on a Ping/Pong is not very helpful, the pingpong measures from the BC applications, which does include BC app/server round trips.

    So: register start; for(i=0 to 100) {BC => AX => PING/pong } register end

    I could have worded this somewhat better. Note however that this round-trip is present in all calls (x++ and IL) and 'should' be a constant factor.

  • Martin Dráb Profile Picture
    237,880 Most Valuable Professional on at

    All right, thank you for this extra explanation. :-)

    So now you ruled out that it might be related to your code and it all seems to be caused by Microsoft platform code.

    I'm trying to come up with a plausible theory about the cause, but I can't think of any if the environments are identical (as far as we can say). I'll give it some thought...

  • Community Member Profile Picture
    on at

    I still don't know what is causing this but I made my timing difference problem go away by making the method to call a configuration setting. On AOS1 I call the IL version, on AOS2 the AX version.

    Strange that it exists, but since it is in the bowels of AX which I can not access, I doubt I will ever figure this out...

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > 🔒一 Microsoft Dynamics AX (Archived)

#1
Martin Dráb Profile Picture

Martin Dráb 4 Most Valuable Professional

#1
Priya_K Profile Picture

Priya_K 4

#3
MyDynamicsNAV Profile Picture

MyDynamicsNAV 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans