Showing posts with label Best Practices. Show all posts
Showing posts with label Best Practices. Show all posts

Friday, September 3, 2021

Things to avoid in APEX (Part-2)

Incase you haven't seen the Part-1 of Things to Avoid in Apex, below is the link

https://adityanthiruchuri.blogspot.com/2021/08/things-to-avoid-in-apex.html


Let us understand few more tips / tricks in this post.

1. Use '==' over 'equals' whenever required

We all know that APEX is not case-sensitive.  But we need to understand that there are few methods in apex, which takes the case-type (lower/upper) into consideration.   When you use the method 'equals' it will return TRUE only if the LHS and RHS are of same value and same case-type. Look at the below example



If you still want to make use of "equals" without taking case-types into consideration you have to either use method "equalsIgnoreCase()" (or) convert both the LHS and RHS into either lower / upper case and then do the comparison, but remember that these methods wont work for "null" values.   Whereas, operator '==' does the job without any such case conversions.  Use method 'equals' to do a comparison only when you want the case-match to be taken into consideration.

2. Concatenation of Strings

If given a requirement to concatenate two strings, we all tend to use the operator '+', but what if I tell you that the method .join() consumes way lesser time than the operator '+'.. Let me elaborate by taking an example.  I am trying to prepare a String by adding all the names of Opportunities separated by a comma.  There are 8500 records present while executing the below logic.


Above code consumed CPU Time of 1049ms.  Now let me execute the same logic by getting rid off the '+' operator by using "join" instead.


Above code consumed CPU Time of just 586ms which is almost 50% lesser than the time taken by the "+" operator.  Also as you are creating a new collection variable, ensure to take the heap size to take into consideration.  You can do the above implementation in your own orgs to get the results.

3. Avoid un-necessary creation of collection variables while preparing Map

Let us take a scenario of preparing Map<Id, list<Opportunity>> where key is AccountId and value will be its associated Opportunities.  Most of us will be writing code like below


In the above logic we have created an extra list at line#6, populated it with the current iterating record and then added it to the map, so that override will happen.  We need to understand that maps are mutable and that gives us the flexibility to modify an element of a map directly without having to add it again.  Consider the logic below


By using the above approach, we completely eliminated the need of creating an extra list and using the same to override the existing value.  

4. Do not use String datatype for holding Id's

I have seen many instances where developers use data-type String to hold value of type "Id". There are many drawbacks of using that approach.  We all know that Id's can be of length 15 or 18 based on the case-sensitivity.  Let us take a simple example to understand the consequence.  I am just hardcoding for our scenario, but keep in thoughts that this is never encouraged as a practice.


Reference : https://salesforce.stackexchange.com/questions/348609/why-this-map-return-null-value/348616

We need to have our code always dynamic in nature.  We can understand from the above example that if we store 15 digit Id in a string, it will fail when used against 18 digit Id and vice-versa.  But if we use the use "Id" data-type rather than string for the above, logic works just smooth.



Hope you find this interesting.  There are still many points to add and few more will be posted soon.   Let me know in the comment section if you have any such tips.  Feedback is much appreciated and thanks for being an awesome reader.  

..Bazingaa..

Friday, August 27, 2021

Things to avoid in APEX (Part-1)

We all strive to write APEX in the best way possible and in this post I will cover few unique guidelines that will help to make your code perform better.

1. Initialization of List

If the ask is to write a SOQL Query to fetch the accounts and store them in a list, 8 out 10 developers will write like below.


We all tend to initialize a list, so that it won't be null.  But that's actually causing more harm by consuming more resources.  We must know that SOQL Query will always return a List of subject which is instantiated.  So in our scenario we are actually doing a shallow copy of the records from the list that was returned from SOQL to the list we created.  So if you get 5,000 records as part of your SOQL, you are copying all the 5000 to your list which is not at all required.  We can avoid the explicit initialization to get rid of the shallow copy by having the logic like below.


PS : Remember that initialization cannot be ignored all the time, but only for few specific scenarios as mentioned above

2. Fetch fields without mentioning them in SOQL

If there is a requirement to fetch the Id and Name of an account, most of us will write the SOQL like below :


But what if I tell you that Id field is not required to be explicitly mentioned in the SOQL Query and will be queried automatically.  Along with the ID, RecordTypeId is one field which is also available for you. 


Also not just this, when there is a relation among objects and your SOQL is on the child object, no matter whichever field you query from the associated parent record, parent record Id will be automatically fetched.


So while writing your SOQL's, have in thoughts that there are few fields available even without querying. 

3. Get value of Formula Field without any DML / SOQL

There could be multiple instances where we do the DML first so that the formula field gets populated and then query for it to use in our logic.  To elaborate my point, let me take an example.  Consider a scenario where there is an object by name "Measurement" and is having 3 fields Length (Number), breadth (Number) and Area (Formula). The area is a formula field which holds the value of length multiplied with breadth. So, in-order to get the value of area, we need to first insert a record and then write a SOQL like below. 


But we can completely avoid writing SOQL and DML for getting the value of the formula field by leveraging a pre-defined method called "recalculateFormuals".  In the below example I have no SOQL/DML but able to get the value of formula field for an un-inserted record on the fly. 



The above approach will be very helpful while writing test classes.

Reference : https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_class_System_Formula.htm

Replace .size() with .isEmpty() wherever applicable

Prior to performing any DML or SOQL where a collection variable is being used, we follow the practice of checking the size of collection to avoid un-necessary SOQL / DML.  


But we need to understand whenever. Size () is used, the processor should traverse through each and every item of the collection for getting the count, but whereas isEmpty() will just check for the very first record in the collection and if found, it returns true, else false. 

So now the time that is consumed by the method. Size () for a collection size of 10000 will be very higher (as it has to traverse through every item present) than the time consumed by the method. IsEmpty() (As the check is made only the very first record).  So whenever you are using. Size () > 0, replace it will. IsEmpty () to avoid time


 Hope you find this interesting.  There are still many points to add and I am planning to post part-2 of this soon.  Let me know in the comment section if you have any such tips.  Feedback is much appreciated and thanks for being an awesome reader.  


..Bazinga..