You all know that trying to minimize calls to the spreadsheet API from Apps Script can dramatically speed things up. Let's take a look at hiding and showing rows and columns, where we're starting from a list of row/column numbers we want to operate on.
Let's say we have arrays like this.
Hide these rows var hide = [3, 5, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 20]
Unhide these var unhide = [0, 1, 2, 4, 6, 10, 19]
(Note that my row number 0 is the first row of data after the column headings - so in Apps Script terms - row 0 is rowIndex 2.)
The obvious way would be hide.forEach(function (d) {
sheet.hideRows(d+2, 1)
});
unhide.forEach( function (d) {
sheet.showRows(d+2, 1)
});
But that would mean making 21 API calls, and not taking advantage of the second argument to hideRows and showRows - the number of rows to hide/show.
So better if we could find a way of optimizing the array so that we minimize the number of calls by making use of consecutive row numbers. Here's a function to do that. /**
* optimize consecitive rows for hiding/unhiding
* @param [list] list of numbers
* @return [{object}] optimized {start:x,count:y}
*/
function optimizeConsecutive (list) {
return list.reduce (function (p,c) {
if (!p.length || p[p.length-1].start + p[p.length-1].count !== c) {
p.push ({
start:c,
count:0
});
}
var prev = p[p.length-1];
prev.count ++;
return p;
} , []);
}
Which transforms our arrays into this. [{
"start": 3,
"count": 1
}, {
"start": 5,
"count": 1
}, {
"start": 7,
"count": 3
}, {
"start": 11,
"count": 8
}, {
"start": 20,
"count": 1
}]
[{
"start": 0,
"count": 3
}, {
"start": 4,
"count": 1
}, {
"start": 6,
"count": 1
}, {
"start": 10,
"count": 1
}, {
"start": 19,
"count": 1
}]
So now we call the API only 10 times rather than 21. optimizeConsecutive(hide).forEach(function (d) {
sheet.hideRows(d.start+2, d.count)
});
optimizeConsecutive(unhide).forEach(function (d) {
sheet.showRows(d.start+2, d.count)
});
Does it make a difference ?
Heres' the optimized version .. just over 2 seconds. [16-09-12 16:04:44:380 BST] Sheet.hideRows([5, 1]) [0.123 seconds]
[16-09-12 16:04:44:591 BST] Sheet.hideRows([7, 1]) [0.21 seconds]
[16-09-12 16:04:44:866 BST] Sheet.hideRows([9, 3]) [0.275 seconds]
[16-09-12 16:04:45:482 BST] Sheet.hideRows([13, 8]) [0.615 seconds]
[16-09-12 16:04:45:772 BST] Sheet.hideRows([22, 1]) [0.289 seconds]
[16-09-12 16:04:45:959 BST] Sheet.showRows([2, 3]) [0.186 seconds]
[16-09-12 16:04:46:142 BST] Sheet.showRows([6, 1]) [0.182 seconds]
[16-09-12 16:04:46:274 BST] Sheet.showRows([8, 1]) [0.131 seconds]
[16-09-12 16:04:46:408 BST] Sheet.showRows([12, 1]) [0.133 seconds]
[16-09-12 16:04:46:572 BST] Sheet.showRows([21, 1]) [0.163 seconds]
And the unoptimized version .. just under 8 seconds. [16-09-12 16:06:34:271 BST] Range.getValues() [0.092 seconds]
[16-09-12 16:06:34:433 BST] Sheet.showRows([2, 1]) [0.157 seconds]
[16-09-12 16:06:34:894 BST] Sheet.showRows([3, 1]) [0.46 seconds]
[16-09-12 16:06:35:251 BST] Sheet.showRows([4, 1]) [0.356 seconds]
[16-09-12 16:06:35:494 BST] Sheet.showRows([6, 1]) [0.242 seconds]
[16-09-12 16:06:35:764 BST] Sheet.showRows([8, 1]) [0.27 seconds]
[16-09-12 16:06:35:952 BST] Sheet.showRows([12, 1]) [0.187 seconds]
[16-09-12 16:06:36:196 BST] Sheet.showRows([21, 1]) [0.243 seconds]
[16-09-12 16:06:36:412 BST] Sheet.hideRows([5, 1]) [0.215 seconds]
[16-09-12 16:06:36:741 BST] Sheet.hideRows([7, 1]) [0.329 seconds]
[16-09-12 16:06:37:056 BST] Sheet.hideRows([9, 1]) [0.314 seconds]
[16-09-12 16:06:37:437 BST] Sheet.hideRows([10, 1]) [0.38 seconds]
[16-09-12 16:06:38:227 BST] Sheet.hideRows([11, 1]) [0.79 seconds]
[16-09-12 16:06:39:119 BST] Sheet.hideRows([13, 1]) [0.891 seconds]
[16-09-12 16:06:39:649 BST] Sheet.hideRows([14, 1]) [0.529 seconds]
[16-09-12 16:06:39:948 BST] Sheet.hideRows([15, 1]) [0.298 seconds]
[16-09-12 16:06:40:186 BST] Sheet.hideRows([16, 1]) [0.238 seconds]
[16-09-12 16:06:40:452 BST] Sheet.hideRows([17, 1]) [0.265 seconds]
[16-09-12 16:06:40:698 BST] Sheet.hideRows([18, 1]) [0.245 seconds]
[16-09-12 16:06:40:920 BST] Sheet.hideRows([19, 1]) [0.222 seconds]
[16-09-12 16:06:41:125 BST] Sheet.hideRows([20, 1]) [0.204 seconds]
[16-09-12 16:06:42:199 BST] Sheet.hideRows([22, 1]) [1.073 seconds]
With just that small sample, we see a 4x improvement. In Apps Script, performance matters a lot if you don't want to hit quota limits.
|