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 Integer
If i <> 0 And 100/i < 20 Then
' Do Something
End If
Using AndAlso
does not cause an error and is also more efficient.
Dim i As Integer
If i <> 0 AndAlso 100/i < 20 Then
' Do Something
End 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 finAccount
Dim Message As String
Dim Success As Boolean
' Assume Success
Success = True
' Load Account
Account = finBL.CreateAccount()
Success = Account.Load("L10000")
' Create Message
If Success Then
If TotalByElementType(isefinElementType.InterestDefault) = 0 Then
Message = "No Default Interest charged."
Else
Message = String.Format("Default Interest charged to date {0}.", finBL.FormatCurrency(TotalByElementType(isefinElementType.InterestDefault), True))
End If
End If
Getting the Total Payments may be slow. This code can be optimised by caching this in a local variable:
Dim Account As finAccount
Dim Message As String
Dim TotalDefaultInterest As Decimal
Dim Success As Boolean
' Assume Success
Success = True
' Load Account
Account = finBL.CreateAccount()
Success = Account.Load("L10000")
' Create Message
If Success Then
TotalDefaultInterest = Account.Calculation.Schedule.TotalByElementType(isefinElementType.InterestDefault)
If TotalDefaultInterest = 0 Then
Message = "No Default Interest charged."
Else
Message = String.Format("Default Interest charged to date {0}.", finBL.FormatCurrency(TotalDefaultInterest, True))
End If
End 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 Integer
Dim kvl as ISKeyValueList
For i = 0 to 100
kvl = finBL.CreateKeyValueList()
' Do Something
Next
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 Integer
Dim kvl as ISKeyValueList
' Initialise
kvl = finBL.CreateKeyValueList()
For i = 0 to 100
kvl.Clear()
' Do Something
Next
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 finAccount
Dim ClientList As String
Dim Success As Boolean
' Assume Success
Success = True
' Load Account
Account = finBL.CreateAccount()
Success = Account.Load("L10000")
' Get Names of all Account Clients
If Success Then
ClientList = GetClientList(Account.AccountId)
End If
End Sub
Private Function GetClientList(accountId As String) As String
Dim Account As finAccount
Dim AccountClient As finAccountClient
Dim ClientList As String
Dim Success As Boolean
' Assume Success
Success = True
' Load Account
Account = finBL.CreateAccount()
Success = Account.Load(accountId)
' Get Names of all Account Clients
If Success Then
For Each AccountClient In Account.Clients
If Len(ClientList) <> 0 Then ClientList &= vbNewLine
ClientList &= AccountClient.ClientName
Next
End If
Return ClientList
End 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.