Coding Best Practices Part 2
This blog outlines coding practices that any professional developer using the finPOWER Connect API should adhere to.
finPOWER Connect is written entirely in VB.NET. All sample scripts are also written in VB.NET. Although C# is an option, Intersoft Systems does not provide support for this.
In this second blog we will look at performance.
Related Blogs
More information is available in the finPOWER Connect Programming Guide.
Top Best Practices
Global Collections
Refer to Part 1.
AndAlso and OrElse
Always use AndAlso and OrElse instead of And and Or.
They shortcut expression evaluation and make for more optimised and robust code.
For example, the example below would cause an error since you are trying to divide 100 by zero. This is because using an And still evaluates the second part of the expression even if the first part fails.
Dim i As IntegerIf i <> 0 And 100/i < 20 Then' Do SomethingEnd If
Using AndAlso does not cause an error and is also more efficient.
Dim i As IntegerIf i <> 0 AndAlso 100/i < 20 Then' Do SomethingEnd If
Caching Values
Certain operations may be expensive i.e. slow, or use a lot of processing power, or database querying. In these circumstances caching values in variables is recommended instead of accessing the multiple times.
Consider the following code:
Dim Account As finAccountDim Message As StringDim Success As Boolean' Assume SuccessSuccess = True' Load AccountAccount = finBL.CreateAccount()Success = Account.Load("L10000")' Create MessageIf Success ThenIf TotalByElementType(isefinElementType.InterestDefault) = 0 ThenMessage = "No Default Interest charged."ElseMessage = String.Format("Default Interest charged to date {0}.", finBL.FormatCurrency(TotalByElementType(isefinElementType.InterestDefault), True))End IfEnd If
Getting the Total Payments may be slow. This code can be optimised by caching this in a local variable:
Dim Account As finAccountDim Message As StringDim TotalDefaultInterest As DecimalDim Success As Boolean' Assume SuccessSuccess = True' Load AccountAccount = finBL.CreateAccount()Success = Account.Load("L10000")' Create MessageIf Success ThenTotalDefaultInterest = Account.Calculation.Schedule.TotalByElementType(isefinElementType.InterestDefault)If TotalDefaultInterest = 0 ThenMessage = "No Default Interest charged."ElseMessage = String.Format("Default Interest charged to date {0}.", finBL.FormatCurrency(TotalDefaultInterest, True))End IfEnd If
Other places where you should cache values include:
- Loops, e.g.
- Don't recalculate values or concatenate Strings unnecessarily within loops. Calculate the value before entering the loop.
- Don't call functions within loops unnecessarily. If the function's return values will not vary with each iteration of the loop, call the function before entering the loop and store the result in a variable. For example:
Dim i As IntegerDim kvl as ISKeyValueListFor i = 0 to 100kvl = finBL.CreateKeyValueList()' Do SomethingNext
Reinitialising the ISKeyValueList object on each iteration of the loop is expensive. This can be optimised by inititialising the object once and then clearing it on every iteration of the loop:
Dim i As IntegerDim kvl as ISKeyValueList' Initialisekvl = finBL.CreateKeyValueList()For i = 0 to 100kvl.Clear()' Do SomethingNext
Pass Objects instead of reloading them
Loading an object takes time, therefore objects should be passed between functions in preference to reloading them.
Consider the following code:
Private Sub LoadAccount(accountId As String)Dim Account As finAccountDim ClientList As StringDim Success As Boolean' Assume SuccessSuccess = True' Load AccountAccount = finBL.CreateAccount()Success = Account.Load("L10000")' Get Names of all Account ClientsIf Success ThenClientList = GetClientList(Account.AccountId)End IfEnd SubPrivate Function GetClientList(accountId As String) As StringDim Account As finAccountDim AccountClient As finAccountClientDim ClientList As StringDim Success As Boolean' Assume SuccessSuccess = True' Load AccountAccount = finBL.CreateAccount()Success = Account.Load(accountId)' Get Names of all Account ClientsIf Success ThenFor Each AccountClient In Account.ClientsIf Len(ClientList) <> 0 Then ClientList &= vbNewLineClientList &= AccountClient.ClientNameNextEnd IfReturn ClientListEnd Function
Exceptions to this rule may include:
- Where a global or module variable already exists holding the object (e.g. a finPOWER Connect Summary Page Script). In these cases there is no need to pass the object around at all since it will be available to all functions.
- Where a function must have the latest version of the object as stored on the database e.g. to ensure it has not been changed by the User or to ensure it contains changes made elsewhere.