Approach
This should be my final update. I reran my tests, setting all Debug Levels
to NONE
except Apex
, which I set to ERROR
. The findings are more or less unchanged: casting beats all other approaches. I added more data, however, to demonstrate the level of difference more rigorously.
I used the following strategy to profile the above in Execute Anonymous
:
static Set<Id> generateDummyIds(Integer size)
{
Set<Id> ids = new Set<Id>();
for (Integer i=0; i<size; i++)
{
String suffix = String.valueOf(i).leftPad(15).replace(' ', '0');
ids.add(Id.valueOf('001' + suffix));
}
return ids;
}
final Integer SET_ELEMENTS = 0;
final Integer ITERATIONS = 1000;
Set<Id> input = generateDummyIds(SET_ELEMENTS);
Long start = Datetime.now().getTime();
for (Integer i = 0; i < ITERATIONS; i++) PerformanceTesting.deserializeToStrings(input);
system.debug(LoggingLevel.ERROR, Datetime.now().getTime() - start);
I used the following value combinations ten times each:
SET_ELEMENTS = 0
with ITERATIONS = 1000
for 10k sample size
SET_ELEMENTS = 1
with ITERATIONS = 1000
for 10k sample size
SET_ELEMENTS = 1000
with ITERATIONS = 50
for 500 sample size
SET_ELEMENTS = 100000
with ITERATIONS = 1
for 10 sample size
Modifications
I added a fourth method out of curiosity, even though OP of that question requested to avoid it. This method provides a baseline against which to measure alternatives.
public static Set<String> loopToStrings(Set<Id> input)
{
Set<String> output = new Set<String>();
for (Id id : input) output.add(id);
return output;
}
I also modified the stringify
method to produce the correct results as noted by @crop1645:
public static Set<String> stringify(Set<Id> input)
{
return (input == null || input.isEmpty()) ? new Set<String>() :
new Set<String>(String.join(new List<id>(input), ',').split(','));
}
Data
Of note is that the deserializeToStrings
and stringify
methods both failed with 100k elements in the set. The former failed due to heap size exceeded, the latter got a REGEX_TOO_COMPLICATED
error.
First let's take a look at milliseconds per call:
0 1 1k 100k
deserialize 0.2498 0.2118 14.290 HEAP ERROR
stringify 0.0657 0.1023 2.276 REGEX ERROR
loop 0.0465 0.0914 17.164 1705.4
cast 0.0385 0.0594 2.000 210.0
Next let's examine calls per second:
0 1 1k 100k
deserialize 4003 4272 70 HEAP ERROR
stringify 15221 9775 439 REGEX ERROR
loop 21505 10941 58 0.59
cast 25974 16835 500 4.76
input
is an empty list; the resulting set<String> has one element with value equal to empty string becausesplit()
on an empty list results in a list of size 1 with member[0] value = empty string. Option 2 has to be written more 'cleverly'set<id> input
; only option 2 has the issue