1

When working in Apex it is not uncommon for us to work with a numeric field that has a 0 scale. To use that with some built in functions we need to use an Integer. To provide an example, let's say we have a field on Account TrainingDays__c. This field always holds a whole number.

To use this field with Date.addDays() we need to convert the Decimal value that acct.TrainingDays__c is represented in to an Integer. For this task we have two options: Integer.valueOf(acct.TrainingDays__c) or (Integer)acct.TrainingDays__c.

I know that there are some differences when working in other languages, but for the given example where the source value is a numeric SObject field:

  • Is there ever a time when one of the methods would throw an exception and the other would not?
  • Is one more performant than the other?
  • Other than code consistency is there any reason to standardize on one approach?
1

For your specific example, there is this third way:

Integer i = acct.TrainingDays__c != null ? acct.TrainingDays__c.intValue() : null;

or:

Integer i = acct.TrainingDays__c != null ? acct.TrainingDays__c.round() : null;

The benefit of using these methods is that they more clearly express what is being done and provide options in how the operation is done (e.g. rounding mode).

Methods like Integer.valueOf make sense when you don't know the type of the argument.

As for using casting for this particular conversion, I'm a little surprised it even works. That observation leads to a reason you haven't included in your list: the most important reason to choose is clarity for someone reading the code (e.g. someone other than you changing the code in 2 years time). Whether the operation takes 1 microsocond or 10 microsoconds is irrelevant if a a 5 millisecond query comes soon after. See e.g. we should forget about small efficiencies, say about 97% of the time.

+1 for sfdcfox's measuring to get the performance figures rather than speculating.

6

Is there ever a time when one of the methods would throw an exception and the other would not?

Yes, there are differences between the two. For example, you can't cast a String to an Integer, but you can use Integer.valueOf to parse a String into an Integer. As a side effect, this means that different constructs are susceptible to different errors. For example:

Object o = '32';
// Following line would throw a runtime exception
//Integer i1 = (Integer)o;
// But this line will return the value 32.
Integer i2 = Integer.valueOf(o);

Is one more performant than the other?

Casting is always faster, but only handles "legal" conversions, such as converting a Decimal or Long to an Integer. An analysis I just did suggests that casting is about 7.8 times faster than using Integer.valueOf, with casting requiring about 0.001679 milliseconds, and Integer.valueOf requiring about 0.013072 milliseconds (edit: normalized out the time required to execute a loop for better comparison).

(Additional Edit): The difference between casting and Integer.valueOf becomes increasingly more pronounced the more verbose your profiling and system log levels are set to. Cranking everything down to a bare minimum, and normalizing the loop and heap allocations, shows that casting is about 0.0008 milliseconds, while Integer.valueOf is about 0.00114 milliseconds, which isn't even twice as expensive. However, since most users operate at a level higher than "no debugging at all", the previous paragraph fairly accurately expresses the typical performance penalty you can expect for a normal production user.

Other than code consistency is there any reason to standardize on one approach?

You should always prefer performance over standardization, but be aware that both casting and valueOf are tools that have different purposes (so you should ideally use both as appropriate). Use casting when you know that you're using a legal cast type, such as Decimal or Long, and use Integer.valueOf when you need the flexibility of also parsing strings.

  • Very interesting with the logging performance. Since my initial question was in regards to numeric sObject fields it sounds like casting is always the preferred approach for that performance benefit. – dsharrison Nov 18 '16 at 22:52
  • 1
    @D.S. Yes, in respect to converting Decimal to Integer, casting is superior to Integer.valueOf for performance, and neither throw exceptions (e.g. NullPointerException/NPE). Of course, when casting down data types, you do need to remember that anything outside of -2^32 and 2^32 will be truncated to fit within this range. One final note, there's also Decimal.intValue, but this throws NPE if the field is null. – sfdcfox Nov 18 '16 at 22:56

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.