8

It is a bit odd we can't evaluate a switch statement directly on SObjectType, so I am trying to determine conclusively which workaround is the most efficient.

Just to verify, I tried to compile this code:

void demo(SObjectType input)
{
    switch on input
    {
        when Account.sObjectType { }
        when else { }
    }
}

And this code generates the error:

Schema.SObjectType is not a valid switch expression type

Bummer. There are workarounds however. The two most obvious that I have come up with:

void demoRecordInstantiation(SObjectType input)
{
    switch on input.newSObject()
    {
        when Account a { }
        when else { }
    }
}
void demoStringTyping(SObjectType input)
{
    switch on String.valueOf(input)
    {
        when 'Account' { }
        when else { }
    }
}

Maybe there are others, so if there is an obvious approach I have missed which performs better or is more readable/maintainable, let me know.

My question is, what approach offers the best performance? If I am calling this method many times in a loop, is the SObjectType.newSObject method resource intensive? Or calling String.valueOf(SObjectType)? Should I consider caching these values?

  • 1
    I will profile this question as time allows, but right now I am not able to perform an in depth analysis and would be happy for someone to beat me to the punch. – Adrian Larson May 17 '19 at 15:52
  • 2
    i've used these workarounds myself and had to wash my hands afterwards. Let's hope that switch on SObjectType comes soon – cropredy May 17 '19 at 16:54
  • 3
    I strongly prefer the former, as at least you maintain concrete object references. – Adrian Larson May 17 '19 at 16:55
7

The when values must be literals, so you cannot use String.valueOf as demonstrated in your second example. That said, using String.valueOf is approximately 10% more efficient when using literal string values:

Long t3, t2, t1 = datetime.now().gettime();
for(Integer i = 0; i < 100000; i++) {
    sobjecttype a = account.sobjecttype;
    switch on a.newsobject() {
        when account ac {

        }
        when contact co {

        }
    }
}
t2 = datetime.now().gettime();
for(Integer i = 0; i < 100000; i++) {
    sobjecttype a = account.sobjecttype;
    switch on string.valueof(a) {
        when 'Account' {

        }
        when 'Contact' {

        }
    }
}
t3 = datetime.now().gettime();
system.debug(t3-t2);
system.debug(t2-t1);

That said, it appears that the actual performance difference is insignificant (less than 0.008 ms per call), so unless you need the performance, choose whichever works best for you.

As an aside, make sure you comment this code for followup later. It has been said salesforce.com would like to include other data types in future releases, and this may include the sObjectType data type as well.

  • 2
    Huh, good to know on that last paragraph. Would be nice to see them add support for this one, as it seems like it would be a very common use case. – Adrian Larson May 17 '19 at 16:46
  • 2
    @AdrianLarson Yes, I've had a number of times since switch came out that I wished I could use sObjectType. It'd be the most efficient version of the switch statement for its use case. – sfdcfox May 17 '19 at 16:48
  • On the plus side, this post is a likely canary if I fail to catch it in the release notes when they do make this change. Seems fair to assume when not if here. – Adrian Larson May 17 '19 at 16:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.