sabell2012
Mega Sage
Mega Sage

NOTE: MY POSTINGS REFLECT MY OWN VIEWS AND DO NOT NECESSARILY REPRESENT THE VIEWS OF MY EMPLOYER, ACCENTURE.

 

DIFFICULTY LEVEL:    INTERMEDIATE
Assumes having taken the class SSNF and has good intermediate level of knowledge and/or familiarity with Scripting in ServiceNow.


Over and over I get asked why I don't use the .getValue() method when working with GlideRecords. My pat answer has always been: PERFORMANCE! The method I use is usually a JavaScript force-to-string; the ol' plus-tick-tick method.

 

I finally got fed up and decided to do an article showing once-and-for-all that this method trounces all the others, and is the reason all of us old JavaScript users use it!

 

So, I came up with the following code: I would loop through each method 20 times. 10 with a small number of records, and 10 with a large number of records. I would then compile the timings and show off the results. THEN I would point at the results, and say; "THERE! THERE! Run the test yourselves if you don't believe me!"

 

This was a bad move on my part. I was wrong. See! I even admit it. Big of me. 😋

 

const ITERATIONLIMIT = 10;

checkSpeeds('incident');
checkSpeeds('cmdb');

function checkSpeeds(tableName) {
	var checkList = [];
	var testResults = create2DArray(3);
	var average = [0,0,0];

	testResults[0] = 'tick-tick, \t' + tableName + '\t';
	testResults[1] = 'getValue, \t' + tableName + '\t';
	testResults[2] = 'toString, \t' + tableName + '\t';

	var checkRecords = new GlideRecord(tableName);
	checkRecords.query();

	for (var j=0; j < 3; j++) {
		for (var i=0; i < ITERATIONLIMIT; i++) {
			checkRecords.restoreLocation();

			var check1 = new Date().getTime(); // grab our start time
			
			checkList = [];
			
			while (checkRecords.next()) {
				if (j == 0) {
					checkList.push(checkRecords.number + '');
				}
				else if (j == 1) {
					checkList.push(checkRecords.getValue('number'));
				}
				else {
					checkList.push(checkRecords.number.toString());
				}
			}

			var millisecs = (new Date().getTime()) - check1;
			testResults[j] += millisecs + 'ms, \t'; // calculate our end time
			average[j] += millisecs;
		}

		testResults[j] += gs.getMessage('\t{0} avg\t {1} records\t', [
			(average[j]/ITERATIONLIMIT),
			checkList.length
		]);
		//testResults[j] += '\t' + (average[j]/checkList.length) + ' avg\t' + checkList.length + ' records\t';
	}

	for (j=0; j < 3; j++) {
		gs.info(testResults[j]); // print off the results
	}
}

// simple function for creating a 2d array
function create2DArray(depth) {
	var result = [];
	
	for (var i=0; i < depth; i++) {
		result.push([]);
	}
	
	return result;
}

 

Here are my results from 2016:

       

Type Table # Records Test 1 Test 2 Test 3 Test 4 Test 5 Test 6 Test 7 Test 8 Test 9 Test 10 Total Wins Average

% Faster Than Next

tick-tick incident 107 records 27 25 23 31 25 28 24 25 24 23 2 25.5  
getValue incident 107 records 22 27 22 23 22 22 22 24 32 23 4 23.9 5.53
toString incident 107 records 21 25 24 22 29 31 27 22 30 22 5 25.3  
tick-tick cmdb 5162 records 784 758 752 724 731 714 690 705 705 743  

730.6

 
getValue cmdb 5162 records 635 626 592 608 566 598 602 607 630 623 10 608.7 16.68
toString cmdb 5162 records 729 806 763 752 721 697 697 726 721 696   730.8  

 

The analysis from 2016:

 

With just a few records getValue edged out the competition by 5.5%. At 5,000 records it became very obvious that some sort of serious optimization has been done; with the percentage now rising to 16.7%! It was also interesting to me that there appeared to be no obvious difference between + '', and .toString(). Wild!

 

I reran the analysis today (11/19/2023) and got the following surprising results (more than once):

     

Type Table # Records Test 1 Test 2 Test 3 Test 4 Test 5 Test 6 Test 7 Test 8 Test 9 Test 10 Total Wins Average

% Faster Than slowest

tick-tick incident 67 records 7 6 9 8 6 7 6 6 6 6 1 6.7  
getValue incident 67 records 7 6 6 6 7 8 6 7 7 6 1 6.5 3.1%
toString incident 67 records 7 6 8 6 6 8 6 7 6 7 0 6.7  
tick-tick cmdb 2786 records 127 133 133 134 134 122 121 131 131 128 2

129.4

 
getValue cmdb 2786 records 121 122 121 121 128 126 127 122 125 125 4 123.8 4.5%
toString cmdb 2786 records 126 127 128 120 128 124 125 124 120 122 3 124.4 4.0%

 

Result analysis?

 

ServiceNow has corrected the disparity. Agreed it isn't the exact same number of records as last time, but it should still show the same stilted difference, right? I am still leaning toward getValue, but its earlier advantages have been more-or-less erased. Notice that in some cases the other two methods won.

 

I went outside, and contemplated life for awhile. This messed with my fundamental understanding of the universe!

 

Anyway, after crying it out on my front porch I went back in and ran a few more tests. Perhaps I had the columns out of order or something…, but no. It came up pretty much the same no matter how I tried to twist the numbers around.

 

So here you go. Of the three methods:

 

  • .toString and + '' are just about the same; with toString edging out the other method only slightly.
  • .getValue is still stronger the more records you throw at it.  

 

Not sure what to do next. Maybe gravity isn't a constant after all.

 

Enjoy!

Steven Bell.

 

If you find this article helps you, don't forget to log in and mark it as "Helpful"!

 

sabell2012_0-1700408493023.png


Originally published on: 7-12-2016 03:55 PM

I updated the code and brought the article into alignment with my new formatting standard.

1 Comment