[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/2in3/2.9.0/build/yui2-profiler/ -> yui2-profiler-debug.js (source)

   1  YUI.add('yui2-profiler', function(Y) {
   2      var YAHOO    = Y.YUI2;
   3      /*
   4  Copyright (c) 2011, Yahoo! Inc. All rights reserved.
   5  Code licensed under the BSD License:
   6  http://developer.yahoo.com/yui/license.html
   7  version: 2.9.0
   8  */
   9  YAHOO.namespace("tool");
  10  
  11  /**
  12   * The YUI JavaScript profiler.
  13   * @module profiler
  14   * @namespace YAHOO.tool
  15   * @requires yahoo
  16   */
  17  
  18  /**
  19   * Profiles functions in JavaScript.
  20   * @namespace YAHOO.tool
  21   * @class Profiler
  22   * @static
  23   */
  24  YAHOO.tool.Profiler = function(){
  25  
  26  
  27      //-------------------------------------------------------------------------
  28      // Private Variables and Functions
  29      //-------------------------------------------------------------------------
  30      
  31      var container   = {},   //Container object on which to put the original unprofiled methods.
  32          report      = {},   //Profiling information for functions
  33          stopwatches = {},   //Additional stopwatch information
  34          
  35          WATCH_STARTED   = 0,
  36          WATCH_STOPPED   = 1,
  37          WATCH_PAUSED    = 2,    
  38          
  39          lang    = YAHOO.lang;
  40  
  41      /**
  42       * Creates a report object with the given name.
  43       * @param {String} name The name to store for the report object.
  44       * @return {Void}
  45       * @method createReport
  46       * @private
  47       */
  48      function createReport(name){
  49          report[name] = {
  50              calls: 0,
  51              max: 0,
  52              min: 0,
  53              avg: 0,
  54              points: []
  55          };      
  56      }
  57      
  58      /**
  59       * Called when a method ends execution. Marks the start and end time of the 
  60       * method so it can calculate how long the function took to execute. Also 
  61       * updates min/max/avg calculations for the function.
  62       * @param {String} name The name of the function to mark as stopped.
  63       * @param {int} duration The number of milliseconds it took the function to
  64       *      execute.
  65       * @return {Void}
  66       * @method saveDataPoint
  67       * @private
  68       * @static
  69       */
  70      function saveDataPoint(name, duration){
  71  
  72          //get the function data
  73          var functionData /*:Object*/ = report[name];
  74          
  75          //just in case clear() was called
  76          if (!functionData){
  77              functionData = createReport(name);
  78          }
  79      
  80          //increment the calls
  81          functionData.calls++;
  82          functionData.points.push(duration);
  83  
  84          //if it's already been called at least once, do more complex calculations
  85          if (functionData.calls > 1) {
  86              functionData.avg = ((functionData.avg*(functionData.calls-1))+duration)/functionData.calls;
  87              functionData.min = Math.min(functionData.min, duration);
  88              functionData.max = Math.max(functionData.max, duration);
  89          } else {
  90              functionData.avg = duration;
  91              functionData.min = duration;
  92              functionData.max = duration;
  93          }                             
  94      
  95      }
  96  
  97      //-------------------------------------------------------------------------
  98      // Singleton Object
  99      //-------------------------------------------------------------------------
 100      
 101      return {
 102      
 103          //-------------------------------------------------------------------------
 104          // Utility Methods
 105          //-------------------------------------------------------------------------        
 106          
 107          /**
 108           * Removes all report data from the profiler.
 109           * @param {String} name (Optional) The name of the report to clear. If
 110           *      omitted, then all report data is cleared.
 111           * @return {Void}
 112           * @method clear
 113           * @static
 114           */
 115          clear: function(name){
 116              if (lang.isString(name)){
 117                  delete report[name];
 118                  delete stopwatches[name];
 119              } else {
 120                  report = {};
 121                  stopwatches = {};
 122              }
 123          },
 124  
 125          /**
 126           * Returns the uninstrumented version of a function/object.
 127           * @param {String} name The name of the function/object to retrieve.
 128           * @return {Function|Object} The uninstrumented version of a function/object.
 129           * @method getOriginal
 130           * @static
 131           */    
 132          getOriginal: function(name){
 133              return container[name];
 134          },
 135      
 136          /**
 137           * Instruments a method to have profiling calls.
 138           * @param {String} name The name of the report for the function.
 139           * @param {Function} method The function to instrument.
 140           * @return {Function} An instrumented version of the function.
 141           * @method instrument
 142           * @static
 143           */
 144          instrument: function(name, method){
 145          
 146              //create instrumented version of function
 147              var newMethod = function () {
 148      
 149                  var start = new Date(),
 150                      retval = method.apply(this, arguments),
 151                      stop = new Date();
 152                  
 153                  saveDataPoint(name, stop-start);
 154                  
 155                  return retval;                
 156              
 157              };     
 158  
 159              //copy the function properties over
 160              lang.augmentObject(newMethod, method);
 161              
 162              //assign prototype and flag as being profiled
 163              newMethod.__yuiProfiled = true;
 164              newMethod.prototype = method.prototype;
 165              
 166              //store original method
 167              container[name] = method;
 168              container[name].__yuiFuncName = name;
 169              
 170              //create the report
 171              createReport(name);
 172  
 173              //return the new method
 174              return newMethod;
 175          },    
 176          
 177          //-------------------------------------------------------------------------
 178          // Stopwatch Methods
 179          //-------------------------------------------------------------------------        
 180          
 181          /**
 182           * Pauses profiling information for a given name.
 183           * @param {String} name The name of the data point.
 184           * @return {Void}
 185           * @method pause
 186           * @static
 187           */        
 188          pause: function(name){
 189              var now = new Date(),
 190                  stopwatch = stopwatches[name];
 191                  
 192              if (stopwatch && stopwatch.state == WATCH_STARTED){
 193                  stopwatch.total += (now - stopwatch.start);
 194                  stopwatch.start = 0;
 195                  stopwatch.state = WATCH_PAUSED;
 196              }
 197          
 198          },
 199          
 200          /**
 201           * Start profiling information for a given name. The name cannot be the name
 202           * of a registered function or object. This is used to start timing for a
 203           * particular block of code rather than instrumenting the entire function.
 204           * @param {String} name The name of the data point.
 205           * @return {Void}
 206           * @method start
 207           * @static
 208           */
 209          start: function(name){
 210              if(container[name]){
 211                  throw new Error("Cannot use '" + name + "' for profiling through start(), name is already in use.");
 212              } else {
 213              
 214                  //create report if necessary
 215                  if (!report[name]){
 216                      createReport(name);
 217                  }
 218                  
 219                  //create stopwatch object if necessary
 220                  if (!stopwatches[name]){             
 221                      stopwatches[name] = {
 222                          state: WATCH_STOPPED,
 223                          start: 0,
 224                          total: 0
 225                      };
 226                  }
 227                  
 228                  if (stopwatches[name].state == WATCH_STOPPED){
 229                      stopwatches[name].state = WATCH_STARTED;
 230                      stopwatches[name].start = new Date();                    
 231                  }
 232  
 233              }
 234          },
 235          
 236          /**
 237           * Stops profiling information for a given name.
 238           * @param {String} name The name of the data point.
 239           * @return {Void}
 240           * @method stop
 241           * @static
 242           */
 243          stop: function(name){
 244              var now = new Date(),
 245                  stopwatch = stopwatches[name];
 246                  
 247              if (stopwatch){
 248                  if (stopwatch.state == WATCH_STARTED){
 249                      saveDataPoint(name, stopwatch.total + (now - stopwatch.start));                    
 250                  } else if (stopwatch.state == WATCH_PAUSED){
 251                      saveDataPoint(name, stopwatch.total);
 252                  }
 253                  
 254                  //reset stopwatch information
 255                  stopwatch.start = 0;
 256                  stopwatch.total = 0;
 257                  stopwatch.state = WATCH_STOPPED;                
 258              }
 259          },
 260      
 261          //-------------------------------------------------------------------------
 262          // Reporting Methods
 263          //-------------------------------------------------------------------------    
 264          
 265          /**
 266           * Returns the average amount of time (in milliseconds) that the function
 267           * with the given name takes to execute.
 268           * @param {String} name The name of the function whose data should be returned.
 269           *      If an object type method, it should be 'constructor.prototype.methodName';
 270           *      a normal object method would just be 'object.methodName'.
 271           * @return {float} The average time it takes the function to execute.
 272           * @method getAverage
 273           * @static
 274           */
 275          getAverage : function (name /*:String*/) /*:float*/ {
 276              return report[name].avg;
 277          },
 278      
 279          /**
 280           * Returns the number of times that the given function has been called.
 281           * @param {String} name The name of the function whose data should be returned.
 282           * @return {int} The number of times the function was called.
 283           * @method getCallCount
 284           * @static
 285           */
 286          getCallCount : function (name /*:String*/) /*:int*/ {
 287              return report[name].calls;    
 288          },
 289          
 290          /**
 291           * Returns the maximum amount of time (in milliseconds) that the function
 292           * with the given name takes to execute.
 293           * @param {String} name The name of the function whose data should be returned.
 294           *      If an object type method, it should be 'constructor.prototype.methodName';
 295           *      a normal object method would just be 'object.methodName'.
 296           * @return {float} The maximum time it takes the function to execute.
 297           * @method getMax
 298           * @static
 299           */
 300          getMax : function (name /*:String*/) /*:int*/ {
 301              return report[name].max;
 302          },
 303          
 304          /**
 305           * Returns the minimum amount of time (in milliseconds) that the function
 306           * with the given name takes to execute.
 307           * @param {String} name The name of the function whose data should be returned.
 308           *      If an object type method, it should be 'constructor.prototype.methodName';
 309           *      a normal object method would just be 'object.methodName'.
 310           * @return {float} The minimum time it takes the function to execute.
 311           * @method getMin
 312           * @static
 313           */
 314          getMin : function (name /*:String*/) /*:int*/ {
 315              return report[name].min;
 316          },
 317      
 318          /**
 319           * Returns an object containing profiling data for a single function.
 320           * The object has an entry for min, max, avg, calls, and points).
 321           * @return {Object} An object containing profile data for a given function.
 322           * @method getFunctionReport
 323           * @static
 324           * @deprecated Use getReport() instead.
 325           */
 326          getFunctionReport : function (name /*:String*/) /*:Object*/ {
 327              return report[name];
 328          },
 329      
 330          /**
 331           * Returns an object containing profiling data for a single function.
 332           * The object has an entry for min, max, avg, calls, and points).
 333           * @return {Object} An object containing profile data for a given function.
 334           * @method getReport
 335           * @static
 336           */
 337          getReport : function (name /*:String*/) /*:Object*/ {
 338              return report[name];
 339          },
 340      
 341          /**
 342           * Returns an object containing profiling data for all of the functions 
 343           * that were profiled. The object has an entry for each function and 
 344           * returns all information (min, max, average, calls, etc.) for each
 345           * function.
 346           * @return {Object} An object containing all profile data.
 347           * @static
 348           */
 349          getFullReport : function (filter /*:Function*/) /*:Object*/ {
 350              filter = filter || function(){return true;};
 351          
 352              if (lang.isFunction(filter)) {
 353                  var fullReport = {};
 354                  
 355                  for (var name in report){
 356                      if (filter(report[name])){
 357                          fullReport[name] = report[name];    
 358                      }
 359                  }
 360                  
 361                  return fullReport;
 362              }
 363          },
 364      
 365          //-------------------------------------------------------------------------
 366          // Profiling Methods
 367          //-------------------------------------------------------------------------   
 368          
 369          /**
 370           * Sets up a constructor for profiling, including all properties and methods on the prototype.
 371           * @param {string} name The fully-qualified name of the function including namespace information.
 372           * @param {Object} owner (Optional) The object that owns the function (namespace or containing object).
 373           * @return {Void}
 374           * @method registerConstructor
 375           * @static
 376           */
 377          registerConstructor : function (name /*:String*/, owner /*:Object*/) /*:Void*/ {    
 378              this.registerFunction(name, owner, true);
 379          },
 380      
 381          /**
 382           * Sets up a function for profiling. It essentially overwrites the function with one
 383           * that has instrumentation data. This method also creates an entry for the function
 384           * in the profile report. The original function is stored on the container object.
 385           * @param {String} name The full name of the function including namespacing. This
 386           *      is the name of the function that is stored in the report.
 387           * @param {Object} owner (Optional) The object that owns the function. If the function
 388           *      isn't global then this argument is required. This could be the namespace that
 389           *      the function belongs to, such as YAHOO.util.Dom, or the object on which it's
 390           *      a method.
 391           * @param {Boolean} registerPrototype (Optional) Indicates that the prototype should
 392           *      also be instrumented. Setting to true has the same effect as calling
 393           *      registerConstructor().
 394           * @return {Void}
 395           * @method registerFunction
 396           * @static
 397           */     
 398          registerFunction : function(name /*:String*/, owner /*:Object*/, registerPrototype /*:Boolean*/) /*:Void*/{
 399          
 400              //figure out the function name without namespacing
 401              var funcName = (name.indexOf(".") > -1 ? 
 402                      name.substring(name.lastIndexOf(".")+1) : name),
 403                  method,
 404                  prototype;
 405                  
 406              //if owner isn't an object, try to find it from the name
 407              if (!lang.isObject(owner)){
 408                  owner = eval(name.substring(0, name.lastIndexOf(".")));
 409              }
 410              
 411              //get the method and prototype
 412              method = owner[funcName];
 413              prototype = method.prototype;
 414              
 415              //see if the method has already been registered
 416              if (lang.isFunction(method) && !method.__yuiProfiled){
 417                  
 418                  //replace the function with the profiling one
 419                  owner[funcName] = this.instrument(name, method);
 420                          
 421                  /*
 422                   * Store original function information. We store the actual
 423                   * function as well as the owner and the name used to identify
 424                   * the function so it can be restored later.
 425                   */
 426                  container[name].__yuiOwner = owner;
 427                  container[name].__yuiFuncName = funcName;  //overwrite with less-specific name
 428                   
 429                  //register prototype if necessary
 430                  if (registerPrototype) {            
 431                      this.registerObject(name + ".prototype", prototype);          
 432                  }
 433      
 434              }
 435          
 436          },
 437              
 438          
 439          /**
 440           * Sets up an object for profiling. It takes the object and looks for functions.
 441           * When a function is found, registerMethod() is called on it. If set to recrusive
 442           * mode, it will also setup objects found inside of this object for profiling, 
 443           * using the same methodology.
 444           * @param {String} name The name of the object to profile (shows up in report).
 445           * @param {Object} owner (Optional) The object represented by the name.
 446           * @param {Boolean} recurse (Optional) Determines if subobject methods are also profiled.
 447           * @return {Void}
 448           * @method registerObject
 449           * @static
 450           */
 451          registerObject : function (name /*:String*/, object /*:Object*/, recurse /*:Boolean*/) /*:Void*/{
 452          
 453              //get the object
 454              object = (lang.isObject(object) ? object : eval(name));
 455          
 456              //save the object
 457              container[name] = object;
 458          
 459              for (var prop in object) {
 460                  if (typeof object[prop] == "function"){
 461                      if (prop != "constructor" && prop != "superclass"){ //don't do constructor or superclass, it's recursive
 462                          this.registerFunction(name + "." + prop, object);
 463                      }
 464                  } else if (typeof object[prop] == "object" && recurse){
 465                      this.registerObject(name + "." + prop, object[prop], recurse);
 466                  }
 467              }
 468          
 469          },    
 470          
 471          /**
 472           * Removes a constructor function from profiling. Reverses the registerConstructor() method.
 473           * @param {String} name The full name of the function including namespacing. This
 474           *      is the name of the function that is stored in the report.
 475           * @return {Void}
 476           * @method unregisterFunction
 477           * @static
 478           */     
 479          unregisterConstructor : function(name /*:String*/) /*:Void*/{
 480                  
 481              //see if the method has been registered
 482              if (lang.isFunction(container[name])){
 483                  this.unregisterFunction(name, true);
 484              }    
 485          },
 486          
 487          /**
 488           * Removes function from profiling. Reverses the registerFunction() method.
 489           * @param {String} name The full name of the function including namespacing. This
 490           *      is the name of the function that is stored in the report.
 491           * @return {Void}
 492           * @method unregisterFunction
 493           * @static
 494           */     
 495          unregisterFunction : function(name /*:String*/, unregisterPrototype /*:Boolean*/) /*:Void*/{
 496                  
 497              //see if the method has been registered
 498              if (lang.isFunction(container[name])){
 499              
 500                  //check to see if you should unregister the prototype
 501                  if (unregisterPrototype){
 502                      this.unregisterObject(name + ".prototype", container[name].prototype);
 503                  }
 504                      
 505                  //get original data
 506                  var owner /*:Object*/ = container[name].__yuiOwner,
 507                      funcName /*:String*/ = container[name].__yuiFuncName;
 508                      
 509                  //delete extra information
 510                  delete container[name].__yuiOwner;
 511                  delete container[name].__yuiFuncName;
 512                  
 513                  //replace instrumented function
 514                  owner[funcName] = container[name];
 515                  
 516                  //delete supporting information
 517                  delete container[name];          
 518              }
 519                  
 520          
 521          },
 522          
 523          /**
 524           * Unregisters an object for profiling. It takes the object and looks for functions.
 525           * When a function is found, unregisterMethod() is called on it. If set to recrusive
 526           * mode, it will also unregister objects found inside of this object, 
 527           * using the same methodology.
 528           * @param {String} name The name of the object to unregister.
 529           * @param {Boolean} recurse (Optional) Determines if subobject methods should also be
 530           *      unregistered.
 531           * @return {Void}
 532           * @method unregisterObject
 533           * @static
 534           */
 535          unregisterObject : function (name /*:String*/, recurse /*:Boolean*/) /*:Void*/{
 536          
 537              //get the object
 538              if (lang.isObject(container[name])){            
 539                  var object = container[name];    
 540              
 541                  for (var prop in object) {
 542                      if (typeof object[prop] == "function"){
 543                          this.unregisterFunction(name + "." + prop);
 544                      } else if (typeof object[prop] == "object" && recurse){
 545                          this.unregisterObject(name + "." + prop, recurse);
 546                      }
 547                  }
 548                  
 549                  delete container[name];
 550              }
 551          
 552          }
 553           
 554  
 555      };
 556  
 557  }();  
 558  
 559  YAHOO.register("profiler", YAHOO.tool.Profiler, {version: "2.9.0", build: "2800"});
 560  
 561  }, '2.9.0' ,{"requires": ["yui2-yahoo"]});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1