Performance
+AL Coding Guidelines
+Performance
+Some guidelines are simply better for performance considerations rather than readability or anything else. In this section, let’s look into some..
+ +diff --git a/404.html b/404.html index 93c12e22..e4593e82 100644 --- a/404.html +++ b/404.html @@ -2,17 +2,17 @@
- +Some guidelines are simply better for performance considerations rather than readability or anything else. In this section, let’s look into some..
+ +<Created by waldo, Described by waldo>
+In general, subscribers have to be put in codeunits. There are a few performance considerations that you should keep in the back of your minds, when designing such a codeunit.
+Let’s discuss all points
+Every time a subscriber gets called, a new instance of the codeunit is being loaded in memory, which takes memory and processing power. The smaller the codeunit, the less memory, and the faster it is.
+Therefore, it’s suggested to split the subscribers by functionality and avoid putting business logic in the actual codeunit. Tip: put all business logic in an “Method Codeunit”.
+Examples:
+codeunit 2037325 "Setup Subs"
+{
+ SingleInstance = true;
+
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::"Manual Setup", 'OnRegisterManualSetup', '', false, false)]
+ local procedure OnRegisterManualSetup(sender: Codeunit "Manual Setup")
+ var
+ AppId: ModuleInfo;
+ NameListLbl: Label 'Linked Texts Framework - List', Locked = true;
+ DescriptionListLbl: Label 'Edit linked texts', Locked = true;
+ KeyWordListLbl: Label 'LT,Distri,Technical,Functional,Reports', Locked = true;
+ NameReportLbl: Label 'Linked Texts Framework - Reports', Locked = true;
+ DescriptionReportLbl: Label 'View linked texts reports', Locked = true;
+ KeyWordReportLbl: Label 'LT,Distri,Technical,Functional,Reports', Locked = true;
+ begin
+ navapp.GetCurrentModuleInfo(AppId);
+ Sender.Insert(NameListLbl, DescriptionListLbl, KeyWordListLbl, page::"LTE Linked Text List", AppId.Id(), "Manual Setup Category"::General);
+ Sender.Insert(NameReportLbl, DescriptionReportLbl, KeyWordReportLbl, page::"LTE Linked Texts Reports", AppId.Id(), "Manual Setup Category"::General);
+ end;
+
+ [EventSubscriber(ObjectType::Codeunit, codeunit::"Manual Setup", 'OnRegisterManualSetup', '', false, false)]
+ local procedure OnRegisterManualSetup(sender: Codeunit "Manual Setup")
+ var
+ AppId: ModuleInfo;
+ NameLayoutLbl: Label 'Report Helper - Layout', Locked = true;
+ DescriptionLayoutLbl: Label 'Set up or update report layout list', Locked = true;
+ KeyWordLayoutLbl: Label 'RH,Distri,Technical,Functional,Reports,Layout', Locked = true;
+ NameCaptionsLbl: Label 'Report Helper - Captions', Locked = true;
+ DescriptionCaptionsLbl: Label 'Set up or update captions list', Locked = true;
+ KeyWordCaptionsLbl: Label 'RH,Distri,Technical,Functional,Reports,Captions', Locked = true;
+ NameFunctionsLbl: Label 'Report Helper - Functions', Locked = true;
+ DescriptionFunctionsLbl: Label 'Set up or disable functions', Locked = true;
+ KeyWordFunctionsLbl: Label 'RH,Distri,Technical,Functional,Reports,Functions', Locked = true;
+ NameDFCLbl: Label 'Report Helper - Default Footer', Locked = true;
+ DescriptionDFCLbl: Label 'Set up or update default footer', Locked = true;
+ KeyWordDFCLbl: Label 'RH,Distri,Technical,Functional,Reports,Default,Footer', Locked = true;
+ begin
+ navapp.GetCurrentModuleInfo(AppId);
+ Sender.Insert(NameLayoutLbl, DescriptionLayoutLbl, KeyWordLayoutLbl, page::"RHE Report Layout List", AppId.Id(), "Manual Setup Category"::General);
+ Sender.Insert(NameCaptionsLbl, DescriptionCaptionsLbl, KeyWordCaptionsLbl, page::"RHE Captions", AppId.Id(), "Manual Setup Category"::General);
+ Sender.Insert(NameFunctionsLbl, DescriptionFunctionsLbl, KeyWordFunctionsLbl, page::"RHE Functions", AppId.Id(), "Manual Setup Category"::General);
+ Sender.Insert(NameDFCLbl, DescriptionDFCLbl, KeyWordDFCLbl, page::"RHE Default Footer Card", AppId.Id(), "Manual Setup Category"::General);
+ end;
+}
+Split into 2 codeunits, and move the business logic out.
+codeunit 2037325 "LTE Setup Subs"
+{
+ SingleInstance = true;
+
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::"Manual Setup", 'OnRegisterManualSetup', '', false, false)]
+ local procedure OnRegisterManualSetup(sender: Codeunit "Manual Setup")
+ var
+ RegisterLTEManualSetup: codeunit "Register LTE Manual Setup";
+ begin
+ RegisterLTEManualSetup.RegisterLTEManualSetup();
+ end;
+}
+
+codeunit 2037324 "RHE Setup Subs"
+{
+ SingleInstance = true;
+
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::"Manual Setup", 'OnRegisterManualSetup', '', false, false)]
+ local procedure OnRegisterManualSetup(sender: Codeunit "Manual Setup")
+ var
+ RegisterRHEManualSetup: codeunit "Register RHE Manual Setup";
+ begin
+ RegisterRHEManualSetup.RegisterRHEManualSetup();
+ end;
+}
+
+
+To avoid the extra “loading of the content” while a subscriber is being executed, use Single Instance codeunit for subscribers. Do take into account, of course, that it would share the state across the entire session.
+codeunit 2037324 "RHE Setup Subs"
+{
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::"Manual Setup", 'OnRegisterManualSetup', '', false, false)]
+ local procedure OnRegisterManualSetup(sender: Codeunit "Manual Setup")
+ var
+ RegisterRHEManualSetup: codeunit "Register RHE Manual Setup";
+ begin
+ RegisterRHEManualSetup.RegisterRHEManualSetup();
+ end;
+}
+codeunit 2037324 "RHE Setup Subs"
+{
+ SingleInstance = true;
+
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::"Manual Setup", 'OnRegisterManualSetup', '', false, false)]
+ local procedure OnRegisterManualSetup(sender: Codeunit "Manual Setup")
+ var
+ RegisterRHEManualSetup: codeunit "Register RHE Manual Setup";
+ begin
+ RegisterRHEManualSetup.RegisterRHEManualSetup();
+ end;
+}
+If possible, only execute the subscriber when really necessary by using Manual Binding.
+ //subscriber - code should actually only run when Color=Red.
+ [EventSubscriber(ObjectType::Table, Database::"Just Some Table WLD", 'OnAfterValidateEvent', 'Message 2', false, false)]
+ local procedure JustDoSomthing(var Rec: Record "Just Some Table WLD"; var xRec: Record "Just Some Table WLD")
+ begin
+ if Rec.color <> 'RED' then
+ exit; //only execute when necessary
+
+ ...
+ end;
+
+ //business logic
+ if JustSomeTable.FindSet() then
+ repeat
+ JustSomeTable.Validate("Message 2", format(Random(1000)));
+ until JustSomeTable.Next() < 1;
+ if JustSomeTable.FindSet() then
+ repeat
+ if JustSomeTable.Color = 'RED' then
+ BindSubscription(DemoSubs);
+
+ JustSomeTable.Validate("Message 2", format(Random(1000)));
+
+ if JustSomeTable.Color = 'RED' then
+ UnbindSubscription(DemoSubs);
+ until JustSomeTable.Next() < 1;
+The reason for this is, that it breaks the batch-calls:
+Avoid subscribers to these events.
+You can discuss this guidelines here.
+You can find discussions on all “Best Practices” here.
+If you don’t find the discussion of this guideline, please feel free to create a new one with the same title as this article.
+