Wednesday 24 July 2013

Apex script statements reduction: "How To write apex code that adds less to script statement governor limit ?"

While I was working on Subscription Sorting for December Release 2012, I came across a requirement when I had to fetch more than 1000 records from the Web Service.
Our apex class was supporting around 500 records to be fetched. Getting results>500 was causing an error like: "Too many script statement 200001".

I search on some forums, discussion boards, blog etc and finally  find the reason behind and it was pretty interesting to know that there are workarounds available to tackle this.

So, let us go step by step.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

What is an Apex script statement ?


Its any coded instruction that performs an action. In Apex, statements must end with a semicolon and can be one of the following types:
  • Assignment, such as assigning a value to a variable
  • Conditional (if-else)
  • Loops
  • Do-while
  • While
  • For
  • Locking
  • Data Manipulation Language (DML)
  • Transaction Control
  • Method Invoking
  • Exception Handling
for ex.

What gets counted into Apex script statements ?

I have seen many developers making there apex code ugly just to reduce the number of script statements. I respect this thought, as the end goal is to never cross or add significantly to the apex script statements governor limits. In this effort we sometimes do some reductions that are not really counted into script limits. Following are the code snippets and there equivalents that  use same script statements.

THE UGLY IF ELSE BLOCK

// UGLY Script statement
if (true) System.debug('true');
else System.debug('false');

// Equivalent more readable form, both on execution count 1 script statement
if (true) {
     System.debug('true');
else {
     System.debug('false');
}

THE UGLY VARIABLE DECLARATION.

// UGLY declaration of variables
String str1, str2, str3, str4;
// You might think this will count as 1 script statement, its actually "4".
// Because short hand notation is expanded by many languages. So why do this 

So there are few examples where developers can make there life really easy by writing well expanded and indented code.
The thumb rule of apex is Any thing ending with semi-colon is script statement !”,  so here are the quick notes about what’s not a script statement.

  • Any Apex Standard class methods that you invoke does not matters how complex its internally is. It will never get counter to your script limits.
  • Any curly braces { }, newlines and tabs you add are not script statements. Add them to make your code more readable.
  • Any conditional evaluations/expressions for ex. if () are not counted into script statement.

How to reduce Apex Script Statements ?

There are ways to do so. Following are some code snippets that explain this:

    Collections like Map, Set, List
     All these collections offer a shorthand way to initialize the collection at the time of declaration. This is really helpful if you are going to insert simple data, as that statement is just counted as 1 script statement. Check the                  example below.    

// Way 1 to declare and populate a Map
     Map < integer , string > My_Map = new Map < integer, string >();
     My_Map.put(1 'a');
     My_Map.put(2 'b');
     My_Map.put(3 'c');
     //NOTE: It uses 4 script statements, so 1 script statement per key/value pair.

   // Way 2 to declare and populate a Map
     Map < integer, string > My_Map = new Map < integer, string > {1 => 'a'2 => 'b'3 => 'c'};
     //NOTE: It uses 1 script statement, that involves map declaration, instantiation and population.
     // Similarly one can create Set and List in following manner, this type on instantiation is counted as single script statement.
     Set aSet = new Set {'a''b''c'};
     List aList = new List{'a''b''c'};

Combining multiple operations into one.
One can do so by wrapping an assignment statement, inside a condition or another assignment statement OR by calling a required API within a statement context. Though this mostly makes code fairly hard to understand, but reduces the number of script statements. Following code snippet illustrates that

// Creating anonymous Set inside List constructor scope, it counts as 1 script statement
     List aList = new List(new Set{'d''e''f'}) ;
// In the above example the set is created in a simple manner but we can go as complex as we want by invoking other methods.

Though there can be many more examples to above, but I really don’t appreciate doing this, as it really makes code hard to read.  A few more script statements are acceptable here.

Who should care about reducing apex script statement ?


If you are writing simple customization for force.com/sfdc, then you really don’t need to bother about this. But this requires some consideration when you are a developer in following scenarios:
  • You are developing a library or utility Apex API that’s will be used by many others. Here any reduction in script statement is pretty useful, for ex. if you are writing something to parse a complex Xml structure, you might quickly add a lot to script statement in such API’s and this will leave less room for client code.
  • Developing for a large force.com customization or project. Here chances are there that many developers will be contributing to same Apex code flow, so keeping room for others will make you scale well.

References


No comments:

Post a Comment

Thank you for visiting. Your comments are highly appreciated.