The performance impact of events

For the people that missed out on the session called ‘Performance: Business Central reloaded for the Cloud’ at the #navtechdays this year, it’s extremely important to catch-up with the topics discussed as this was the most informative session at the event.
One key takeaway of the session is about that magic thing that solves all our problems when going from C/AL to AL, that’s right, we’re talking about events!

Oh, and by the way, the recording of that session can be found here.

I knew that subscribing to, for example, the OnModify event would destroy the o-so-efficient MODIFYALL, but have you thought about what’s really going on behind the scenes when an event is raised?

Whenever an event is raised it should figure out who’s subscribing to it and then it needs to trigger that subscriber, but in order to trigger that subscriber, an instance of the object in which the subscriber resides should be created in memory.
Obviously creating instances of objects cost time, especially when those objects contain a lot of functions, variables etc., but how much time are we talking about and is this something we should consider when writing code?

During this session at the TechDays Microsoft showed the following examples/results:


Let’s draw some conclusions:
  • Calling publishers is almost free
  • If there are subscribers, manual bound and single instance static/automatic subscribers are giving you the best performance
  • The size of the object in which the subscriber resides has a huge impact on the performance because the entire object needs to be created in memory, especially when the subscribing object is non-single-instance.

Naturally, after seeing those results, one would think events are slow or that you should set all your subscribing codeunits to single instance.
But let’s be realistic, when do we trigger 1 million publishers/subscribers?
Yes, there are a lot of event publishers and yes people subscribe to many of those events but let’s not draw conclusions just yet, I’m the type of guy that doesn’t believe it until he sees it so let’s prepare a few similar scenarios in a test codeunit but then execute them 10 000 times instead of 1000 000 times.

This is what the code looks like:

And the results:



Even when we call the publishers ‘only’ 10 000 times the difference is still clearly visible, but we’re talking milliseconds here…
So should we set all of our subscriber codeunits to single instance? I don’t think so.
Next to that single instance codeunits usually indicate bad architecture and I just really abominate them!

Luckily there are other options to consider, let’s go over them one by one.


Pick your event binding mechanism
Will you go for static/automatic or for manual?

Subscriber object size
In case of non-single-instance the performance gets worse the bigger the subscribing codeunit gets, in other words, codeunits that subscribe to events should be as small as possible and in my opinion those subscribing codeunits should only consume the event (and maybe check for the RunTrigger parameter in case of table operations) and then directly call another codeunit to do get the job done. (You can already notice the difference when you add, for example, 10 variables to the subscribing codeunit)

Carefully pick the events you subscribe to
You simply should not want to subscribe to, for example, the OnAfterGetRecord trigger of a page to retrieve some more data from the database and fill a variable on the page, especially not when running in the cloud, where every database call becomes more expensive.

Until next time!

4 Comments

Luc van Vugt · December 13, 2018 at 10:03 am

Great resume, Richard. Thanx.

Stephan Weidmann · December 14, 2018 at 1:30 pm

How does the OnModify-Trigger of a tableextension
impact the performance?

Stephan

    Richard Robberse · December 14, 2018 at 1:50 pm

    Hi Stephan,

    The OnModify trigger of a table extension works like as if you’re using the old-fashioned OnModify trigger in C/AL, it is called after the OnModify trigger of the table but before writing to the database.
    I expect that the OnModify trigger of a table extension is more efficient than subscribing to the OnBeforeModfy/OnAfterModify event because events are resolved at runtime.
    Unfortunately, I have nothing in place to actually prove it, sounds like an interesting test 🙂

    What might help is to have a look at this blog post where Arend-Jan explains all the different triggers, events and its execution order.

The performance impact of events - Robberse - Dynamics 365 Business Central/NAV User Group - Dynamics User Group · December 12, 2018 at 11:22 pm

[…] Richard Robberse 2018-12-12 11:53 PM 0 comments 0 views Mirror post […]

Leave a Reply to The performance impact of events - Robberse - Dynamics 365 Business Central/NAV User Group - Dynamics User Group Cancel reply

Your email address will not be published. Required fields are marked *