
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
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"!
Originally published on: 7-12-2016 03:55 PM
I updated the code and brought the article into alignment with my new formatting standard.
- 750 Views
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.