How to Avoid Excessive Looping in Salesforce Triggers?

Spread the love

Question

I am relatively new to Salesforce development and have been exploring different design patterns to write efficient and maintainable code. In my current structure, I have a trigger, a handler class, and a service class that processes records. Each service method iterates over the same set of records for different operations. As the number of methods grows, I find myself looping through the same records multiple times, which seems inefficient. Here’s an example of my structure:

TriggSer

trigger OpportunityTrigger on Opportunity (before insert, before update, after insert, after update) {
    SObjectTriggerHandler.run(new OpportunityBO());
}

Handler

public with sharing class OpportunityBO extends SObjectTriggerHandler {
    private List<Opportunity> opportunities;

    public OpportunityBO() {
        super();
        this.opportunities = super.newList;
    }

    @Override
    protected void onBeforeInsert() {
        new OpportunityService(this.opportunities).method1().method2().method3();
    }

    @Override
    protected void onAfterUpdate() {
        new OpportunityService(this.opportunities).method4();
    }
}

Service

public with sharing class OpportunityService {
    private List<Opportunity> opportunities;

    public OpportunityService(List<Opportunity> opps) {
        this.opportunities = opps;
    }

    public OpportunityService method1() {
        for (Opportunity opp : opportunities) {
            // Some logic
        }
        return this;
    }

    public OpportunityService method2() {
        for (Opportunity opp : opportunities) {
            // Some logic
        }
        return this;
    }

    public OpportunityService method3() {
        for (Opportunity opp : opportunities) {
            // Some logic
        }
        return this;
    }

    public OpportunityService method4() {
        for (Opportunity opp : opportunities) {
            // Some logic
        }
        return this;
    }
}

I want to avoid excessive looping and improve the overall efficiency of my code. What are some strategies or design patterns I can use to achieve this?

Answer

The short answer is that excessive looping in itself is rarely a problem until it becomes a performance bottleneck. Focus on making your code readable, testable, and compliant with governor limits. Here are several strategies and considerations:

1. Consolidate Logic in a Single Loop

Instead of having separate loops in different service methods, consolidate the logic into a single loop. This avoids iterating over the same records multiple times.

public OpportunityService processRecords() {
    for (Opportunity opp : opportunities) {
        if (someCondition) {
            // Logic from method1
        }
        if (anotherCondition) {
            // Logic from method2
        }
        // Additional logic from other methods
    }
    return this;
}

In your handler, call processRecords instead of chaining multiple methods.

2. Use Map-Based Processing

If your logic is based on specific criteria, consider using a Map to group or organize records before processing. This reduces redundant checks and loops.

public OpportunityService groupAndProcess() {
    Map<String, List<Opportunity>> groupedRecords = new Map<String, List<Opportunity>>();
    for (Opportunity opp : opportunities) {
        String key = getGroupKey(opp);
        if (!groupedRecords.containsKey(key)) {
            groupedRecords.put(key, new List<Opportunity>());
        }
        groupedRecords.get(key).add(opp);
    }

    for (String key : groupedRecords.keySet()) {
        List<Opportunity> group = groupedRecords.get(key);
        // Process each group
    }
    return this;
}

private String getGroupKey(Opportunity opp) {
    // Logic to determine the grouping key
    return opp.StageName;
}

3. Don’t Optimize Prematurely

The Salesforce governor limits are designed to ensure efficient code execution. Benchmarking shows that looping is not inherently expensive. For example:

  • A bare loop iterating over 10,000 records uses ~5 CPU time units.
  • A loop processing 10,000 SObjects uses ~25 CPU time units.
  • Salesforce provides 39,000 CPU time units per synchronous transaction.

Focus on avoiding expensive operations like SOQL and DML within loops rather than worrying about the loops themselves.

4. Measure and Profile

Before refactoring for performance, measure the actual CPU time usage to confirm that looping is the issue. You can use simple benchmarks to understand where the bottlenecks are:

Long startTime = Limits.getCpuTime();
for (Opportunity opp : opportunities) {
    // Logic here
}
Long endTime = Limits.getCpuTime();
System.debug('CPU Time: ' + (endTime - startTime));

While consolidating logic and using maps can reduce redundant looping, avoid over-optimizing without evidence of performance issues. Prioritize readability, testability, and proper use of governor limits. When performance does become a concern, measure and refine based on actual data.

Real-Time Project-Based Salesforce Course to Kick Start Your Career

Our Salesforce Course is thoughtfully designed to offer a deep understanding of the Salesforce platform, equipping you with the necessary skills to thrive in the CRM industry. The program covers essential modules like Salesforce Admin, Developer, and AI, seamlessly combining foundational knowledge with hands-on experience. By working on practical projects and real-life assignments, you’ll develop the expertise to tackle intricate business challenges using Salesforce solutions. Our skilled instructors ensure you gain both technical expertise and industry-specific insights to excel in the Salesforce ecosystem.

In addition to mastering technical concepts, our Salesforce training in Pune provides personalized coaching, exam preparation, and interview guidance to enhance your career opportunities. You will have access to a range of study materials, practical project experience, and one-on-one support throughout your learning journey. By the end of the course, you’ll be fully prepared for certification exams and equipped with the real-world problem-solving skills employers highly value. Begin your Salesforce career with us and explore limitless career possibilities. Register for a Free Demo today!

Open Chat
1
Dear Sir/Madam
How can I help you?