Skip to content

Instantly share code, notes, and snippets.

@jfwberg
Last active July 2, 2024 21:25
Show Gist options
  • Save jfwberg/fd107b9febc39062627a2ab16e178c8d to your computer and use it in GitHub Desktop.
Save jfwberg/fd107b9febc39062627a2ab16e178c8d to your computer and use it in GitHub Desktop.
Apex Multi-Dimensional Array Padding Performance Test
/**
* @description Testing script for padding multi-dimensional arrays in Salesforce Apex
* @author Justus van den Berg (jfwberg@gmail.com)
* @url https://medium.com/@justusvandenberg/salesforce-apex-optimization-maps-vs-multi-dimensional-arrays-lists-3703b9aaaf79
* @note Execute anonymous script, performance depends on the time of day and org it runs on
*/
// Test Settings
Integer numX = 90;
Integer numY = 90;
Integer numZ = 90;
// Class level variables
Integer sizeX = 0;
Integer[] sizeY = new Integer[]{};
Integer[][] sizeZ = new Integer[][]{};
// Execute the data orchestration
orchestrateData();
// Simple orchestration method
void orchestrateData(){
// Create a three dimentional array
Entity[][][] entities = new Entity[][][]{};
// Apply pre-padding with max values
padArray(entities,numX,numY,numZ);
// Register timings
Integer st = Limits.getCpuTime();
Integer sh = Limits.getHeapSize();
setEntityTest(entities);
Integer eh = Limits.getHeapSize();
Integer et = Limits.getCpuTime();
getEntityTest(entities);
Integer feh = Limits.getHeapSize();
Integer fet = Limits.getCpuTime();
// Output the numbers
System.debug('Number of entities : ' + (numX * numY * numZ));
System.debug('CPU Time SET : ' + (et-st));
System.debug('Heap Used SET : ' + ((Decimal)((eh -sh)/1000)).format() + ' KB');
System.debug('CPU Time GET : ' + (fet-et));
System.debug('Heap Used GET : ' + ((Decimal)((feh-eh)/1000)).format() + ' KB');
}
// Method for testing the getter
void getEntityTest(Entity[][][] entities){
for(Integer x=0;x<numX;x++){
for(Integer y=0;y<numY;y++){
for(Integer z=0;z<numZ;z++){
Entity e = entities[x][y][z];
}
}
}
}
// Method for testing the setter
void setEntityTest(Entity[][][] entities){
for(Integer x=0;x<numX;x++){
for(Integer y=0;y<numY;y++){
for(Integer z=0;z<numZ;z++){
setEntity(entities, x, y, z);
}
}
}
}
/**
* Method that adds an object at a specific location in the array
*/
void setEntity(Entity[][][] entities, Integer x, Integer y, Integer z){
// Check if the X cooridinate is out of bounds in the entities lists
if(x >= sizeX){
// Start at the last index of the entities lists and add a child list
// for each index that is out of bounds
for(Integer i = sizeX-1; i < x; i++){
entities.add(new Entity[][]{});
// Update the value in sizeX
sizeX++;
// Start the counter for each Y coordinate
sizeY.add(0);
sizeZ.add(new Integer[]{});
}
}
// Check if the Y cooridinate is out of bounds in the entites[x] list
if(y >= sizeY[x]){
// Store the current size, this is faster than referencing the counter array all the time
Integer currentSizeY = sizeY[x];
// Start at the last index of the entities[x] lists and add a child list
// for each index that is out of bounds
for(Integer i = sizeY[x]-1; i < y; i++){
entities[x].add(new Entity[]{});
// Increment the current size
currentSizeY++;
// Start the counter for the
sizeZ[x].add(0);
}
// update the size array with the new value
sizeY[x] = currentSizeY;
}
// Check if the Z cooridinate is out of bounds in the entites[x][y] list
if(z >= sizeZ[x][y]){
// Store the current size, this is faster than referencing the counter array all the time
Integer currentSizeZ = sizeZ[x][y];
// Start at the last index of the entities[x][y] lists and add a NULL value
// for each index that is out of bounds
for(Integer i = sizeZ[x][y]-1; i < z; i++){
entities[x][y].add(null);
currentSizeZ++;
}
// Update te
sizeZ[x][y] = currentSizeZ;
}
// Add the entity to the array
entities[x][y][z] = new Entity(x,y,z);
}
// Method for padding the array
void padArray(Entity[][][] entities, Integer x, Integer y, Integer z){
// Check if the X cooridinate is out of bounds in the entities lists
if(x >= sizeX){
// Start at the last index of the entities lists and add a child list
// for each index that is out of bounds
for(Integer i = sizeX-1; i < x; i++){
entities.add(new Entity[][]{});
// Update the value in sizeX
sizeX++;
// Start the counter for each Y coordinate
sizeY.add(0);
sizeZ.add(new Integer[]{});
}
}
// Check if the Y cooridinate is out of bounds in the entites[x] list
if(y >= sizeY[x]){
// Store the current size, this is faster than referencing the counter array all the time
Integer currentSizeY = sizeY[x];
// Start at the last index of the entities[x] lists and add a child list
// for each index that is out of bounds
for(Integer i = sizeY[x]-1; i < y; i++){
entities[x].add(new Entity[]{});
// Increment the current size
currentSizeY++;
// Start the counter for the
sizeZ[x].add(0);
}
// update the size array with the new value
sizeY[x] = currentSizeY;
}
// Check if the Z cooridinate is out of bounds in the entites[x][y] list
if(z >= sizeZ[x][y]){
// Store the current size, this is faster than referencing the counter array all the time
Integer currentSizeZ = sizeZ[x][y];
// Start at the last index of the entities[x][y] lists and add a NULL value
// for each index that is out of bounds
for(Integer i = sizeZ[x][y]-1; i < z; i++){
entities[x][y].add(null);
currentSizeZ++;
}
// Update te
sizeZ[x][y] = currentSizeZ;
}
}
/**
* Basic class example of a cell
*/
class Entity{
Integer x;
Integer y;
Integer z;
Entity(Integer x, Integer y, Integer z){
this.x = x;
this.y = y;
this.z = z;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment