+ Start a Discussion
Forza di SognoForza di Sogno 

Would like to improve efficiency of nested loops

Hi, 

I have below code that works fine, but I feel it could be more efficient (and hence faster). Here is the use case:
1. I have a parent account and X children accounts.
2. A custom event created at the parent account level propagates to all children account (this is built and works fine).
3. Say there are 100 child account and all the custom events are in sync with the parent - now the 101st child account is added (i.e. new account record with the designated parent account)
4. Now all existing custom events from the parent account need to be copied to the newbie account.

This code is triggered on the account after insert, before update. It currently takes about 20 seconds to import 2,000 (child) accounts.

Thanks.
public static void AddEventstoNewResidences(List<Account> newlist, Map<ID, Account> newmap)
{ 
List<Pickup_Event__c> lstResidenceEvents = new List<Custom_Event__c>();
Set<ID> IDParentAccts = new Set<ID>(); 

for(Account filldata : newlist)
{
   IDParentAccts.add(filldata.ParentId);
}

List<Custom_Event__c> lstParentPickups = 
   [Select Account__c, ...., etc.
   from Custom_Event__c 
   where Account__c in :IDParentAccts];

if(lstParentPickups.size()>0)
{
   List<Custom_Event__c> lstNewPickupsforNewResidence = new List<Custom_Event__c>();
   Map<Id, Custom_Event__c> mapEvents = new Map<Id, Custom_Event__c>( lstParentPickups );

// Here is my issue...I'm looping through all children accounts and all pick-ups, to match up the child's parent with the event's 'parent'
for(Account childAccts : newmap.values())
{
   for(Pickup_Event__c lstPickupEvents : lstParentPickups)
   {
       if(childAccts.ParentId == mapEvents.get(lstPickupEvents.Id).Account__c)   // this line probably can be done more efficiently
       {
           Custom_Event__c oResidenceEvent = new Custom_Event__c(
           Account__c = childAccts.Id,
           Name = mapEvents.get(lstPickupEvents.Id).Event_Type__c + ' - ' + sEventDate,
           Event_Type__c = mapEvents.get(lstPickupEvents.Id).Event_Type__c,
           Must_Sign_Up_By__c = mapEvents.get(lstPickupEvents.Id).Must_Sign_Up_By__c,
           , ....
          PIN_Event_ID__c = mapEvents.get(lstPickupEvents.Id).Id,
         );

        lstNewPickupsforNewResidence.add( oResidenceEvent );

     } // if(childAccts.ParentId == mapEvents.get(lstPickupEvents.Id).Account__c)

   } // for(Pickup_Event__c lstPickupEvents : lstParentPickups)

} // for(Account childAccts : mapChildAccts.values())

if(lstNewPickupsforNewResidence.size() > 0)
{ 
   insert lstNewPickupsforNewResidence;
}

} // if(lstParentPickups.size()>0)

}

 
Best Answer chosen by Forza di Sogno
Amit Chaudhary 8Amit Chaudhary 8

Please try below code:-
public static void AddEventstoNewResidences(List<Account> newlist, Map<ID, Account> newmap)
{ 
List<Pickup_Event__c> lstResidenceEvents = new List<Custom_Event__c>();
Set<ID> IDParentAccts = new Set<ID>(); 

for(Account filldata : newlist)
{
   IDParentAccts.add(filldata.ParentId);
}

List<Custom_Event__c> lstParentPickups = 
   [Select Account__c, ...., etc.
   from Custom_Event__c 
   where Account__c in :IDParentAccts];

if(lstParentPickups.size()>0)
{
   List<Custom_Event__c> lstNewPickupsforNewResidence = new List<Custom_Event__c>();
   Map<Id, Custom_Event__c> mapEvents = new Map<Id, Custom_Event__c>( lstParentPickups );
   // Create a Map like below
   Map<String , List<Custom_Event__c> > mapAccountWiseCustomEvent = new Map<String,Custom_Event__c> ();
   for(Custom_Event__c obj : lstParentPickups )
   {
		if(mapAccountWiseCustomEvent.containsKey(obj.Account__c) )
		{
			List<Custom_Event__c> lstCustEvent = mapAccountWiseCustomEvent.get(obj.Account__c);
			lstCustEvent.add(obj);
		}
		else
		{	
			List<Custom_Event__c> lstCustEvent = new List<Custom_Event__c>();
			lstCustEvent.add(obj);
			mapAccountWiseCustomEvent.put(obj.Account__c,lstCustEvent);
		}
   }
   
   
// Here is my issue...I'm looping through all children accounts and all pick-ups, to match up the child's parent with the event's 'parent'
for(Account childAccts : newmap.values())
{
    //  then check like below
	if( mapAccountWiseCustomEvent.containsKey(childAccts.ParentId) )
	{
	   for(Pickup_Event__c lstPickupEvents : mapAccountWiseCustomEvent.get(childAccts.ParentId) )
	   {
           Custom_Event__c oResidenceEvent = new Custom_Event__c(
           Account__c = childAccts.Id,
           Name = mapEvents.get(lstPickupEvents.Id).Event_Type__c + ' - ' + sEventDate,
           Event_Type__c = mapEvents.get(lstPickupEvents.Id).Event_Type__c,
           Must_Sign_Up_By__c = mapEvents.get(lstPickupEvents.Id).Must_Sign_Up_By__c,
           , ....
           PIN_Event_ID__c = mapEvents.get(lstPickupEvents.Id).Id,
          );
          lstNewPickupsforNewResidence.add( oResidenceEvent );
        } 
    }
} 
if(lstNewPickupsforNewResidence.size() > 0)
{ 
   insert lstNewPickupsforNewResidence;
}

} // if(lstParentPickups.size()>0)

}


NOTE: This code has not been tested and may contain typographical or logical errors


 

All Answers

Amit Chaudhary 8Amit Chaudhary 8

Please try below code:-
public static void AddEventstoNewResidences(List<Account> newlist, Map<ID, Account> newmap)
{ 
List<Pickup_Event__c> lstResidenceEvents = new List<Custom_Event__c>();
Set<ID> IDParentAccts = new Set<ID>(); 

for(Account filldata : newlist)
{
   IDParentAccts.add(filldata.ParentId);
}

List<Custom_Event__c> lstParentPickups = 
   [Select Account__c, ...., etc.
   from Custom_Event__c 
   where Account__c in :IDParentAccts];

if(lstParentPickups.size()>0)
{
   List<Custom_Event__c> lstNewPickupsforNewResidence = new List<Custom_Event__c>();
   Map<Id, Custom_Event__c> mapEvents = new Map<Id, Custom_Event__c>( lstParentPickups );
   // Create a Map like below
   Map<String , List<Custom_Event__c> > mapAccountWiseCustomEvent = new Map<String,Custom_Event__c> ();
   for(Custom_Event__c obj : lstParentPickups )
   {
		if(mapAccountWiseCustomEvent.containsKey(obj.Account__c) )
		{
			List<Custom_Event__c> lstCustEvent = mapAccountWiseCustomEvent.get(obj.Account__c);
			lstCustEvent.add(obj);
		}
		else
		{	
			List<Custom_Event__c> lstCustEvent = new List<Custom_Event__c>();
			lstCustEvent.add(obj);
			mapAccountWiseCustomEvent.put(obj.Account__c,lstCustEvent);
		}
   }
   
   
// Here is my issue...I'm looping through all children accounts and all pick-ups, to match up the child's parent with the event's 'parent'
for(Account childAccts : newmap.values())
{
    //  then check like below
	if( mapAccountWiseCustomEvent.containsKey(childAccts.ParentId) )
	{
	   for(Pickup_Event__c lstPickupEvents : mapAccountWiseCustomEvent.get(childAccts.ParentId) )
	   {
           Custom_Event__c oResidenceEvent = new Custom_Event__c(
           Account__c = childAccts.Id,
           Name = mapEvents.get(lstPickupEvents.Id).Event_Type__c + ' - ' + sEventDate,
           Event_Type__c = mapEvents.get(lstPickupEvents.Id).Event_Type__c,
           Must_Sign_Up_By__c = mapEvents.get(lstPickupEvents.Id).Must_Sign_Up_By__c,
           , ....
           PIN_Event_ID__c = mapEvents.get(lstPickupEvents.Id).Id,
          );
          lstNewPickupsforNewResidence.add( oResidenceEvent );
        } 
    }
} 
if(lstNewPickupsforNewResidence.size() > 0)
{ 
   insert lstNewPickupsforNewResidence;
}

} // if(lstParentPickups.size()>0)

}


NOTE: This code has not been tested and may contain typographical or logical errors


 
This was selected as the best answer
Forza di SognoForza di Sogno
Thank you!  The code works, now I just need to get my head around the use of lists within maps.  Thanks again.