I'm trying to make sure I'm building this code as efficiently as possible, but one questions keeps lingering: When I assign a variable to a method, am I slowing down the code every time it's called?
My Example: (Yes, I'm technically using Google Apps Script, not JS, but I think the question applies to both)
Let's say I want to display the Subject of every Message in every Thread in my Gmail inbox 5 times (for some reason). Here's how I'd see that:
function myFunction(){
let allThreads = GmailApp.getInboxThreads();
var text = "";
for(let x = 0 ; x < allThreads.length ; x ){
let thisThread = x;
let allMessages = thisThread.getMessages();
for(let y = 0 ; y < allMessages.length ; y ){
let thisMessage = y;
let thisSubject = thisMessage.getSubject();
let someNumber = 5;
for( let z = 0; z < someNumber ; z ){
text = " " thisSubject;
}
}
}
Logger.log(text);
}
So, the actual question (finally): Am I calling the getSubject()
method EVERY time I'm using the "thisSubject" variable?
Or even worse; Am I running
GmailApp.getInboxThreads()[x].getMessages()[y].getSubject()
every time?
I'm barely a programmer, but would converting it to a string, rather than a reference to a method (or function) make the code run faster? Especially if we're talking referencing it 1,000 times instead of 5.
for example:
//Replace
let thisSubject = thisMessage.getSubject();
//With
let thisSubject = JSON.parse(JSON.stringify(thisMessage.getSubject()));
Then, if we're expanding on that, would finding a way to Stringify
only the necessary parts of even GmailApp.getInboxThreads
be logical?
To throw another example out there for clarity; If I'm calling Google's SpreadsheetApp to get a sheet name such as:
let mySpreadsheet = SpreadsheetApp.openById('abc123xyz');
let mySheets = mySpreadsheet.getSheets();
let thisSheet = mySheets[1];
let sheetName = thisSheet.getName();
Am I killing my code each time I use sheetName
by re-opening the spreadsheet, getting all the sheets in it, picking out the 2nd then pulling it's name all over again?
Or am I cacheing(cache-ing?) an instance of each result of the methods and pulling from them instead?
CodePudding user response:
Am I calling the
getSubject()
method EVERY time I'm using the "thisSubject" variable?
No. In the inner loop (that runs allThreads.length * allMessages.length
tiems), you call it once, on the line:
let allMessages = thisThread.getMessages();
The line initializes a variable named allMessages
and has it point to an array in memory. Elsewhere when allMessages
is referenced, that existing array is looked up.
Note that you probably have a bug here:
for(let y = 0 ; y < allMessages.length ; y ){
let thisMessage = y;
let thisSubject = thisMessage.getSubject();
You probably meant to do
for(let y = 0 ; y < allMessages.length ; y ){
let thisMessage = allMessages[y];
let thisSubject = thisMessage.getSubject();
or, even better, don't mess with indicies at all, and use iterators and const
:
for (const thisMessage of allMessages) {
const thisSubject = thisMessage.getSubject();
// ...
Am I killing my code each time I use sheetName by re-opening the spreadsheet, getting all the sheets in it, picking out the 2nd then pulling it's name all over again?
No - .getName()
only runs once, and puts its result into memory, and sheetName
is a variable that points to that value in memory. Further references to sheetName
are trivial lookups to the existing value in memory.
Or am I cacheing(cache-ing?) an instance of each result of the methods and pulling from them instead?
That's right.
In general, caching function call results can be useful. For example, it's better to avoid:
for (const value of someArray) {
const someOtherValue = getSomeValue();
// more loop body...
Because someOtherValue
doesn't depend on what's being iterated over, you could do
const someOtherValue = getSomeValue();
for (const value of someArray) {
// more loop body...
and avoid the repeated calls of getSomeValue
. But you aren't making such a mistake anywhere in your code; don't worry.