Google Apps Script V8 vs Rhino 的“日志”非常慢?

Posted

技术标签:

【中文标题】Google Apps Script V8 vs Rhino 的“日志”非常慢?【英文标题】:Very slow "Logs" with Google Apps Script V8 vs Rhino? 【发布时间】:2020-06-09 18:53:26 【问题描述】:

使用 Rhino,日志对话框(“command + Enter”或视图菜单中的日志)会立即显示日志。但是,对于使用 V8 引擎的测试项目,即使是最简单的日志也需要 10-20 秒才能加载,并显示消息“等待日志,请稍候...”

“Logger.log”或“console.log”加载日志都很慢。有没有其他人经历过同样类型的缓慢?新引擎会出现这种情况吗?

这是我用于测试的一个基本函数:

function logTest() 
 Logger.log("log test");

【问题讨论】:

【参考方案1】:

我注意到了同样的事情,并且已经存在一个问题。

我一直在使用下面的脚本。这可能不是防弹的,但对我来说,这比等待日志要好。我还注意到,如果您遇到错误并转到查看执行,那么即使在我们将它们放在脚本编辑器上之前,日志现在似乎就已经出现了。

问题链接:https://issuetracker.google.com/issues/149519063

function MyLogger(s,t=5) 
  const cs=CacheService.getScriptCache();
  const cached=cs.get("Logger");
  const ts=Utilities.formatDate(new Date(), SpreadsheetApp.getActive().getSpreadsheetTimeZone(), "yy/MM/dd HH:mm:ss")
  if(cached) 
    var v=Utilities.formatString('%s<br />[%s] - %s',cached,ts,s);   
  else
    var v=Utilities.formatString('[%s] - %s',ts,s);
  
  cs.put("Logger",v,t);
  SpreadsheetApp.getUi().showModelessDialog(htmlService.createHtmlOutput(v), 'My Logger');

MyLogger() 的另一个版本:

function MyLogger(s,d=true,w=800,h=400,t=5) 
  const cs=CacheService.getScriptCache();
  const cached=cs.get("Logger");
  const ts=Utilities.formatDate(new Date(), SpreadsheetApp.getActive().getSpreadsheetTimeZone(), "MM|dd|HH:mm:ss")
  if(cached) 
    var v=Utilities.formatString('%s<br />[%s] - %s',cached,ts,s);   
  else
    var v=Utilities.formatString('[%s] - %s',ts,s);
  
  cs.put("Logger",v,t);
  //allows logging without displaying.
  if(d) 
    const a='<br /><input type="button" value="Exit" onClick="google.script.host.close();" />';
    const b='<br /><input type="button" value="Exit" onClick="google.script.host.close();" /><br />';
    SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutput(b+v+a).setWidth(w).setHeight(h), 'My Logger');
  

【讨论】:

此外,我发现将日志行通过电子邮件发送给我比等待日志更快。我也不认为他们会解决这个问题。 这是 google google 长期忽视它的重要工具……这是怎么回事?是否与有关新应用脚本 IDE 即将问世的传言有关? @Cooper 我不确定如何使用您的自定义记录器。目前它可能是一个可行的替代方案。【参考方案2】:

自定义记录器的另一种简单方法(用于工作表) 定义此函数以写入“日志”表

const log=(...items)=>
  SpreadsheetApp.getActive().getSheetByName("log").appendRow(items)

给定一个名为 log 的工作表,它会在调用时将参数附加到新行的单元格中

log(1,0,2,"a","b", "etc")

还具有在通过 Web 应用程序执行调用时创建日志的好处(据我所知,这似乎没有以可检索的方式调用 Logger)。

【讨论】:

【参考方案3】:

我对@blueSkys 代码做了一些修改

编辑 1:添加了获取数组的条款

 const log=(...data)=>
 for (i=0; i< data.length;i++)
  if(typeof data[i] === 'object')
  data[i] = data[i].join("//");
;
;
data.unshift(new Date());
  SpreadsheetApp.openById('1E9s2vI21eRlcnoqaVAF4wCUm4Ojn2Lpv62TM6Xw17Z4').getSheetByName('log').appendRow(data);

还为详细指南创建了视频

https://youtu.be/JQpbB5lR4eY

【讨论】:

【参考方案4】:

感谢您的洞察,下面的代码在 GAS 中运行良好:

/**
 * @description Class: Logger helper, writes log information to tab sheet 'log' for the active spreadsheet 
 * @tutorial https://***.com/questions/24342748/why-does-console-log-say-undefined-and-then-the-correct-value
 * @param N/A
 * @return Object
 */
class ConsoleX 
  constructor()
    this.setSS('**** Log Initialized ****');
    this.timeStart = 0;
    this.timerBase = ;
  ;
  
  log(...data)
    let dataY = '';
    data.forEach(c => 
      dataY += c;
    )
    this.setSS(`$[dataY]`);
    Logger.log(`$[dataY]`);
  ;
  
  setSS(data)
    data = [data];
    data.unshift(new Date());
    SpreadsheetApp.getActive().getSheetByName(logFileName).appendRow(data);
  ;
  
  getLogs(dataX)
    this.setSS(`$[dataX]\n$Logger.getLog()`);
  

  time(data = 'base1')
    let dateX = new Date();
    this.timerBase[data] = dateX.getTime();
  ;
  
  timeEnd(data = 'base1')
    let dateX = new Date();
   this.log(`$data: $(dateX.getTime() - this.timerBase[data])/1000(ms)`);
  
  ;
  
  clear() 
  SpreadsheetApp.getActive().getSheetByName(logFileName).clear(contentsOnly: true);

  
;// END ConsoleX


/**
 * @description Function: Test logging methods 
 * @tutorial https://***.com/questions/24342748/why-does-console-log-say-undefined-and-then-the-correct-value
 * @param AS PER METHOD
 * @return undefine
 */
function testLog()
  let testdata = name:'hello', value:'world';
  Logger.log('From Logger: ', testdata);
  test = new ConsoleX();
  test.time('**** Time')
  test.log('**** Standard Log: HELLO WORLD');
  test.log('**** Templating Log: THIS IS GOOD: ', 10*10, ` and $100/2`);
  test.getLogs('**** Logger Historical Data: Looking Good :)');
  test.getLogs();
  test.timeEnd('**** Time')
;

function testClear()
  test = new ConsoleX();
  test.clear();

;

【讨论】:

【参考方案5】:

下面的函数帮了我大忙……又快又脏:

    function logOut(message)
      var ui = SpreadsheetApp.getUi();
      var html  = HtmlService.createHtmlOutput('<h1>'+message+'</h1>');
      ui.showModalDialog(html,'Logs');
    

它会创建一个弹出窗口,显示通过 Logger.log(message) 显示的内容

【讨论】:

以上是关于Google Apps Script V8 vs Rhino 的“日志”非常慢?的主要内容,如果未能解决你的问题,请参考以下文章

[C#]VS2017使用google v8 Javascript引擎

Google chrome vs nodejs(v8)的性能?

允许匿名访问 Google Apps Script Web 应用程序(Google Apps 帐户)

该脚本工作正常,但不在“google-apps-script”中

Google-apps-script 函数 CHAR() 和 CODE()

Google-Apps-Script 无法使用 getDataRange().setValues() 写回数据库