0

I am doing an update an opportunity from a event, in the trigger I have this

List<Opportunity> opportunitiesToUpdate = new List<Opportunity>(); for(Event anEvent : events) { if(String.isNotBlank(anEvent.WhatId) && anEvent.WhatId.getSObjectType().getDescribe().getName() == 'Opportunity') { opportunitiesToUpdate.add(new Opportunity( Id = anEvent.WhatId, xxx__c = anEvent.xx__c )); } } update opportunitiesToUpdate; 

My question is, how expensive is anEvent.WhatId.getSObjectType().getDescribe().getName() == 'Opportunity'? should I just check the suffex of the Id instead such as

String.valueOf(anEvent.WhatId)).startsWith('006') 

2 Answers 2

7

I would use:

anEvent.WhatId?.getSObjectType() == Opportunity.SObjectType 

so you avoid the describe call that is relatively expensive (taking a few milliseconds). This is also a cleaner form of the type check: you are comparing two SObjectType values. The ?. avoids a null pointer exception if WhatId is ever null.

A benefit of Apex compared to most programming languages is that the names of the database tables (SObjects) and columns (fields) are available as compile-time checked enum-like SObjectType and SObjectField references. This is for both the platform's standard SObjects and any custom SObjects your create. So stick with those rather than using strings.

4

tl;dr

This is almost certainly a micro-optimization.
Don't worry about it, you aren't running it enough times to make any significant impact on the CPU limit. If you are running into the CPU limit, there are certainly other places you should be looking to improve first

longer

This is something that's easy enough to benchmark on your own. A simple benchmark is to just run the code in a loop, and also run an "empty" loop so you can subtract the inherent loop time from whatever it is you're trying to measure.

Event evt = [SELECT Id, WhatId FROM Event WHERE What.Type = 'Opportunity' LIMIT 1]; Integer t1; Integer t2; Integer iterations = 10000; // Baseline loop cost with one declaration and assignment t1 = Limits.getCPUTime(); for(Integer i = 0; i < iterations; i++) { Boolean b = true; } t2 = Limits.getCPUTime(); System.debug((t2-t1) + ' cpu units'); // The thing we want to check t1 = Limits.getCPUTime(); for(Integer i = 0; i < iterations; i++) { Boolean b = evt.WhatId.getSObjectType().getDescribe().getName() == 'Opportunity'; } t2 = Limits.getCPUTime(); System.debug((t2-t1) + 'cpu units'); System.debug(Decimal.valueOf(t2-t1)/iterations + ' cpu time per evaluation'); // A slightly improved version of the check t1 = Limits.getCPUTime(); for(Integer i = 0; i < iterations; i++) { Boolean b = evt.WhatId?.getSObjectType() == Opportunity.SObjectType; } t2 = Limits.getCPUTime(); System.debug((t2-t1) + 'cpu units'); System.debug(Decimal.valueOf(t2-t1)/iterations + ' cpu time per evaluation'); 

Running that multiple times (to warm up any caches that Salesforce is using)...

run basic loop getDescribe().getName() getSObjectType() == Opportunity.SObjectType
1 7 165 127
2 7 162 124
3 12 243 204
4 7 160 130
5 10 178 137

over 10k iterations, the "improved" solution runs about 30-40 CPU time less than the .getDescribe().getName() version of the check.

Just do whatever is consistent with the rest of your codebase and/or whatever is easier to read or takes less typing.

String.valueOf(anEvent.WhatId).startsWith('006') uses about 70 CPU time over 10k iterations. If you put that check into another method though, the CPU time used shoots up to be about 110-120.

So I take that to mean that the majority of the CPU time used is just in the overhead associated with calling/returning from methods.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.