Efficient way to write apex code
Set.contains() vs. List.contains()
Why minor collection choices dictate transaction scaling and CPU governor limits in Apex.
"Guess what? Small programmatic choices matter immensely in multi-tenant environments."
If you’re having a cup of tea, pause for a moment. The next two minutes will reveal a simple yet overlooked reality in Salesforce development. Lists and Sets are our absolute go-to collections during a typical development cycle. However, after looking at the mathematical reality behind how the compiler evaluates them, you will definitely double-check your code before deploying.
The Benchmark Setup
Let’s take two collection variants—a List<Integer> and a Set<Integer>—and load them with 100,000 identical elements. Which data structure yields faster lookup performance when running a .contains() check? Let's look at how the execution engine processes both.
Approach A Approach A: The List Implementation
List<Integer> listInteger = new List<Integer>();
for (Integer i = 0; i < 100000; i++) {
listInteger.add(i);
}
Long start = DateTime.now().getTime();
System.debug('Element Found: ' + listInteger.contains(100000));
Long finish = DateTime.now().getTime();
System.debug('List Execution Time: ' + (finish - start) + 'ms');
Under the hood, checking if a List contains an item requires iterating sequentially through the indices. If the target element is at the end of the collection (or completely missing), the runtime engine must execute up to $n$ comparisons. For 100,000 records, that represents a worst-case scenario of 100,000 operations, scaling linearly as your dataset grows.
Approach B Approach B: The Set Implementation
Set<Integer> setInteger = new Set<Integer>();
for (Integer i = 0; i < 100000; i++) {
setInteger.add(i);
}
Long start = DateTime.now().getTime();
System.debug('Element Found: ' + setInteger.contains(100000));
Long finish = DateTime.now().getTime();
System.debug('Set Execution Time: ' + (finish - start) + 'ms');
Sets leverage internal hash tables. When evaluating a match, a hash function calculates a unique index address for the element instantly. Instead of looking through every record, the runtime jumps straight to the bucket location. This lookup requires constant time—$O(1)$ performance—meaning whether your collection contains 10 elements or 1,000,000, the evaluation speed remains practically instantaneous.
Key Takeaway for Your Next Coding Saga
When processing high volumes of records within trigger loops, avoiding Apex CPU time-out limits is vital. If your technical architecture requires frequently scanning an array to see if a record ID or string value matches, always store those reference lookup parameters inside a Set instead of a List. It changes an expensive, performance-draining loop into an instantaneous hash validation. Show your code some #SetLove.
Comments
Post a Comment