SoftwareTester
SoftwareTester

Reputation: 1090

how to speedup several hundred calls DriveApp.getFolderById(id)

I noticed folder = DriveApp.getFolderById(id); takes a lot of time and I would like to know if there is a faster way of retrieving hundreds of folders by their id.

I stored info about pathes and folder-Ids in scriptProperties. Without doing that building the tree takes about 45 seconds.

If I use that and provide a 'dummy'name (= method C) the whole function, containing the code below plus other code, takes just below 1 second.

If I get the names of the folders the normal way by 315 times using methode A (folder = DriveApp.getFolderByid(id)) it takes 27 seconds.

I can optimize this by (effectively) removing calls to getFolderById for folders that have several parents (= method B), but still that takes 22 seconds.

Using DriveApp.getFolders() and prepare the names before the loop (= method D) will reduce time to about 4 seconds. Workable, but still quite long.

   for (var i=1; i<numPathes; i++)
   { // Create treeItems using pathes generated
      var folderPath   = pathes[i];
      var arrPathes    = folderPath.split(underscore);
      var numArrPathes = arrPathes.length;

      var folderIndex = arrPathes[--numArrPathes];
      var parentIndex = arrPathes[--numArrPathes];

      var folderId   = folderIds[folderIndex];

   ///////////// Alternatives
   // Method A) --> takes 27 seconds
      var folder     = DriveApp.getFolderById(folderId);
      var folderName = folder.getName();         // The normal way

   // Method B) --> takes 22 seconds
      var folderName = folderNames[folderIndex]; // Prepared before the current loop

   // Method C) --> takes 1 second  (just for reference)
      var foldeName = folderId;   // Obtained by folder.getId() before (= dummy)

   // Method D) --> takes 4 seconds
      var folderName = folderNames[folderId]; // Prepared using DriveApp.getFolders) 

   // Method E) --> takes 1 second
      var folderName = folderNames[folderId]; // Using cacheService (mentioned by Zig Mandel)
   ///////////// End alternatives


      var txtFolder = underscore + folderId + underscore + folderPath;
      var chk = appLocal.createCheckBox(folderName).setValue(status)
                        .setId(chkPrefix + txtFolder).setName(chkPrefix + txtFolder)
                        .addClickHandler(onChangeStatusChkTreeItem);
      var tri = appLocal.createTreeItem(chk).setId(triPrefix + txtFolder);
      treeItems[i] = tri;
      treeItems[parentIndex].addItem(tri);
   }

   tree.addItem(treeItems[0]); // Add the root to the tree --> all treeItems will be added as well

So my question is if there is a method for obtaining several hundreds of calls to getFolderId(id) fast? I think about caching, but how?

To me it seems GAS lacks a (fast?) map from ids to folders.

EDIT-1

I implemented caching , mapping folder ids to folder names (method E). Currently I use a trigger to start updating the cache and scriptProperties every 5 hours and 50 minutes. I will implement validation of the data in the background using a trigger while the program is running, updating the cache and rebuild the tree if required.

This approach makes it possible to show a tree containing hundreds of folders within a few seconds and without the user waiting for the UI to appear.

Upvotes: 1

Views: 300

Answers (1)

Zig Mandel
Zig Mandel

Reputation: 19835

There is no way to improve the call times to the google apis.
However, if the folder names dont change often you can cache them in a public cache (see cache services) for up to 6 hours by mapping the folder id (property) to the folder name (cache value). Dont use getAllFolders as it has a maximum limit and may not get them all.

Upvotes: 0

Related Questions