diff -r 000000000000 -r 40c8f766c9b8 src/cm/media/js/lib/yui/yui_3.0.0b1/api/Profiler.js.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cm/media/js/lib/yui/yui_3.0.0b1/api/Profiler.js.html Mon Nov 23 15:14:29 2009 +0100 @@ -0,0 +1,674 @@ + + +
+ + /**
+ * The YUI JavaScript profiler.
+ * @module profiler
+ * @requires yui
+ */
+
+ //-------------------------------------------------------------------------
+ // Private Variables and Functions
+ //-------------------------------------------------------------------------
+
+ var container = {}, //Container object on which to put the original unprofiled methods.
+ report = {}, //Profiling information for functions
+ stopwatches = {}, //Additional stopwatch information
+
+ WATCH_STARTED = 0,
+ WATCH_STOPPED = 1,
+ WATCH_PAUSED = 2,
+
+ //shortcuts
+ L = Y.Lang;
+
+ /* (intentionally not documented)
+ * Creates a report object with the given name.
+ * @param {String} name The name to store for the report object.
+ * @return {Void}
+ * @method createReport
+ * @private
+ */
+ function createReport(name){
+ report[name] = {
+ calls: 0,
+ max: 0,
+ min: 0,
+ avg: 0,
+ points: []
+ };
+ }
+
+ /* (intentionally not documented)
+ * Called when a method ends execution. Marks the start and end time of the
+ * method so it can calculate how long the function took to execute. Also
+ * updates min/max/avg calculations for the function.
+ * @param {String} name The name of the function to mark as stopped.
+ * @param {int} duration The number of milliseconds it took the function to
+ * execute.
+ * @return {Void}
+ * @method saveDataPoint
+ * @private
+ * @static
+ */
+ function saveDataPoint(name, duration){
+
+ //get the function data
+ var functionData /*:Object*/ = report[name];
+
+ //just in case clear() was called
+ if (!functionData){
+ functionData = createReport(name);
+ }
+
+ //increment the calls
+ functionData.calls++;
+ functionData.points.push(duration);
+
+ //if it's already been called at least once, do more complex calculations
+ if (functionData.calls > 1) {
+ functionData.avg = ((functionData.avg*(functionData.calls-1))+duration)/functionData.calls;
+ functionData.min = Math.min(functionData.min, duration);
+ functionData.max = Math.max(functionData.max, duration);
+ } else {
+ functionData.avg = duration;
+ functionData.min = duration;
+ functionData.max = duration;
+ }
+
+ }
+
+ //-------------------------------------------------------------------------
+ // Public Interface
+ //-------------------------------------------------------------------------
+
+ /**
+ * Profiles functions in JavaScript.
+ * @class Profiler
+ * @static
+ */
+ Y.Profiler = {
+
+ //-------------------------------------------------------------------------
+ // Utility Methods
+ //-------------------------------------------------------------------------
+
+ /**
+ * Removes all report data from the profiler.
+ * @param {String} name (Optional) The name of the report to clear. If
+ * omitted, then all report data is cleared.
+ * @return {Void}
+ * @method clear
+ * @static
+ */
+ clear: function(name){
+ if (L.isString(name)){
+ delete report[name];
+ delete stopwatches[name];
+ } else {
+ report = {};
+ stopwatches = {};
+ }
+ },
+
+ /**
+ * Returns the uninstrumented version of a function/object.
+ * @param {String} name The name of the function/object to retrieve.
+ * @return {Function|Object} The uninstrumented version of a function/object.
+ * @method getOriginal
+ * @static
+ */
+ getOriginal: function(name){
+ return container[name];
+ },
+
+ /**
+ * Instruments a method to have profiling calls.
+ * @param {String} name The name of the report for the function.
+ * @param {Function} method The function to instrument.
+ * @return {Function} An instrumented version of the function.
+ * @method instrument
+ * @static
+ */
+ instrument: function(name, method){
+
+ //create instrumented version of function
+ var newMethod = function () {
+
+ var start = new Date(),
+ retval = method.apply(this, arguments),
+ stop = new Date();
+
+ saveDataPoint(name, stop-start);
+
+ return retval;
+
+ };
+
+ //copy the function properties over
+ Y.mix(newMethod, method);
+
+ //assign prototype and flag as being profiled
+ newMethod.__yuiProfiled = true;
+ newMethod.prototype = method.prototype;
+
+ //store original method
+ container[name] = method;
+ container[name].__yuiFuncName = name;
+
+ //create the report
+ createReport(name);
+
+ //return the new method
+ return newMethod;
+ },
+
+ //-------------------------------------------------------------------------
+ // Stopwatch Methods
+ //-------------------------------------------------------------------------
+
+ /**
+ * Pauses profiling information for a given name.
+ * @param {String} name The name of the data point.
+ * @return {Void}
+ * @method pause
+ * @static
+ */
+ pause: function(name){
+ var now = new Date(),
+ stopwatch = stopwatches[name];
+
+ if (stopwatch && stopwatch.state == WATCH_STARTED){
+ stopwatch.total += (now - stopwatch.start);
+ stopwatch.start = 0;
+ stopwatch.state = WATCH_PAUSED;
+ }
+
+ },
+
+ /**
+ * Start profiling information for a given name. The name cannot be the name
+ * of a registered function or object. This is used to start timing for a
+ * particular block of code rather than instrumenting the entire function.
+ * @param {String} name The name of the data point.
+ * @return {Void}
+ * @method start
+ * @static
+ */
+ start: function(name){
+ if(container[name]){
+ throw new Error("Cannot use '" + name + "' for profiling through start(), name is already in use.");
+ } else {
+
+ //create report if necessary
+ if (!report[name]){
+ createReport(name);
+ }
+
+ //create stopwatch object if necessary
+ if (!stopwatches[name]){
+ stopwatches[name] = {
+ state: WATCH_STOPPED,
+ start: 0,
+ total: 0
+ };
+ }
+
+ if (stopwatches[name].state == WATCH_STOPPED){
+ stopwatches[name].state = WATCH_STARTED;
+ stopwatches[name].start = new Date();
+ }
+
+ }
+ },
+
+ /**
+ * Stops profiling information for a given name.
+ * @param {String} name The name of the data point.
+ * @return {Void}
+ * @method stop
+ * @static
+ */
+ stop: function(name){
+ var now = new Date(),
+ stopwatch = stopwatches[name];
+
+ if (stopwatch){
+ if (stopwatch.state == WATCH_STARTED){
+ saveDataPoint(name, stopwatch.total + (now - stopwatch.start));
+ } else if (stopwatch.state == WATCH_PAUSED){
+ saveDataPoint(name, stopwatch.total);
+ }
+
+ //reset stopwatch information
+ stopwatch.start = 0;
+ stopwatch.total = 0;
+ stopwatch.state = WATCH_STOPPED;
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ // Reporting Methods
+ //-------------------------------------------------------------------------
+
+ /**
+ * Returns the average amount of time (in milliseconds) that the function
+ * with the given name takes to execute.
+ * @param {String} name The name of the function whose data should be returned.
+ * If an object type method, it should be 'constructor.prototype.methodName';
+ * a normal object method would just be 'object.methodName'.
+ * @return {float} The average time it takes the function to execute.
+ * @method getAverage
+ * @static
+ */
+ getAverage : function (name /*:String*/) /*:float*/ {
+ return report[name].avg;
+ },
+
+ /**
+ * Returns the number of times that the given function has been called.
+ * @param {String} name The name of the function whose data should be returned.
+ * @return {int} The number of times the function was called.
+ * @method getCallCount
+ * @static
+ */
+ getCallCount : function (name /*:String*/) /*:int*/ {
+ return report[name].calls;
+ },
+
+ /**
+ * Returns the maximum amount of time (in milliseconds) that the function
+ * with the given name takes to execute.
+ * @param {String} name The name of the function whose data should be returned.
+ * If an object type method, it should be 'constructor.prototype.methodName';
+ * a normal object method would just be 'object.methodName'.
+ * @return {float} The maximum time it takes the function to execute.
+ * @method getMax
+ * @static
+ */
+ getMax : function (name /*:String*/) /*:int*/ {
+ return report[name].max;
+ },
+
+ /**
+ * Returns the minimum amount of time (in milliseconds) that the function
+ * with the given name takes to execute.
+ * @param {String} name The name of the function whose data should be returned.
+ * If an object type method, it should be 'constructor.prototype.methodName';
+ * a normal object method would just be 'object.methodName'.
+ * @return {float} The minimum time it takes the function to execute.
+ * @method getMin
+ * @static
+ */
+ getMin : function (name /*:String*/) /*:int*/ {
+ return report[name].min;
+ },
+
+ /**
+ * Returns an object containing profiling data for a single function.
+ * The object has an entry for min, max, avg, calls, and points).
+ * @return {Object} An object containing profile data for a given function.
+ * @method getFunctionReport
+ * @static
+ * @deprecated Use getReport() instead.
+ */
+ getFunctionReport : function (name /*:String*/) /*:Object*/ {
+ return report[name];
+ },
+
+ /**
+ * Returns an object containing profiling data for a single function.
+ * The object has an entry for min, max, avg, calls, and points).
+ * @return {Object} An object containing profile data for a given function.
+ * @method getReport
+ * @static
+ */
+ getReport : function (name /*:String*/) /*:Object*/ {
+ return report[name];
+ },
+
+ /**
+ * Returns an object containing profiling data for all of the functions
+ * that were profiled. The object has an entry for each function and
+ * returns all information (min, max, average, calls, etc.) for each
+ * function.
+ * @return {Object} An object containing all profile data.
+ * @static
+ */
+ getFullReport : function (filter /*:Function*/) /*:Object*/ {
+ filter = filter || function(){return true;};
+
+ if (L.isFunction(filter)) {
+ var fullReport = {};
+
+ for (var name in report){
+ if (filter(report[name])){
+ fullReport[name] = report[name];
+ }
+ }
+
+ return fullReport;
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ // Profiling Methods
+ //-------------------------------------------------------------------------
+
+ /**
+ * Sets up a constructor for profiling, including all properties and methods on the prototype.
+ * @param {string} name The fully-qualified name of the function including namespace information.
+ * @param {Object} owner (Optional) The object that owns the function (namespace or containing object).
+ * @return {Void}
+ * @method registerConstructor
+ * @static
+ */
+ registerConstructor : function (name /*:String*/, owner /*:Object*/) /*:Void*/ {
+ this.registerFunction(name, owner, true);
+ },
+
+ /**
+ * Sets up a function for profiling. It essentially overwrites the function with one
+ * that has instrumentation data. This method also creates an entry for the function
+ * in the profile report. The original function is stored on the container object.
+ * @param {String} name The full name of the function including namespacing. This
+ * is the name of the function that is stored in the report.
+ * @param {Object} owner (Optional) The object that owns the function. If the function
+ * isn't global then this argument is required. This could be the namespace that
+ * the function belongs to or the object on which it's
+ * a method.
+ * @param {Boolean} registerPrototype (Optional) Indicates that the prototype should
+ * also be instrumented. Setting to true has the same effect as calling
+ * registerConstructor().
+ * @return {Void}
+ * @method registerFunction
+ * @static
+ */
+ registerFunction : function(name /*:String*/, owner /*:Object*/, registerPrototype /*:Boolean*/) /*:Void*/{
+
+ //figure out the function name without namespacing
+ var funcName = (name.indexOf(".") > -1 ?
+ name.substring(name.lastIndexOf(".")+1) : name),
+ method,
+ prototype;
+
+ //if owner isn't an object, try to find it from the name
+ if (!L.isObject(owner)){
+ owner = eval(name.substring(0, name.lastIndexOf(".")));
+ }
+
+ //get the method and prototype
+ method = owner[funcName];
+ prototype = method.prototype;
+
+ //see if the method has already been registered
+ if (L.isFunction(method) && !method.__yuiProfiled){
+
+ //replace the function with the profiling one
+ owner[funcName] = this.instrument(name, method);
+
+ /*
+ * Store original function information. We store the actual
+ * function as well as the owner and the name used to identify
+ * the function so it can be restored later.
+ */
+ container[name].__yuiOwner = owner;
+ container[name].__yuiFuncName = funcName; //overwrite with less-specific name
+
+ //register prototype if necessary
+ if (registerPrototype) {
+ this.registerObject(name + ".prototype", prototype);
+ }
+
+ }
+
+ },
+
+
+ /**
+ * Sets up an object for profiling. It takes the object and looks for functions.
+ * When a function is found, registerMethod() is called on it. If set to recrusive
+ * mode, it will also setup objects found inside of this object for profiling,
+ * using the same methodology.
+ * @param {String} name The name of the object to profile (shows up in report).
+ * @param {Object} owner (Optional) The object represented by the name.
+ * @param {Boolean} recurse (Optional) Determines if subobject methods are also profiled.
+ * @return {Void}
+ * @method registerObject
+ * @static
+ */
+ registerObject : function (name /*:String*/, object /*:Object*/, recurse /*:Boolean*/) /*:Void*/{
+
+ //get the object
+ object = (L.isObject(object) ? object : eval(name));
+
+ //save the object
+ container[name] = object;
+
+ for (var prop in object) {
+ if (typeof object[prop] == "function"){
+ if (prop != "constructor" && prop != "superclass"){ //don't do constructor or superclass, it's recursive
+ this.registerFunction(name + "." + prop, object);
+ }
+ } else if (typeof object[prop] == "object" && recurse){
+ this.registerObject(name + "." + prop, object[prop], recurse);
+ }
+ }
+
+ },
+
+ /**
+ * Removes a constructor function from profiling. Reverses the registerConstructor() method.
+ * @param {String} name The full name of the function including namespacing. This
+ * is the name of the function that is stored in the report.
+ * @return {Void}
+ * @method unregisterFunction
+ * @static
+ */
+ unregisterConstructor : function(name /*:String*/) /*:Void*/{
+
+ //see if the method has been registered
+ if (L.isFunction(container[name])){
+ this.unregisterFunction(name, true);
+ }
+ },
+
+ /**
+ * Removes function from profiling. Reverses the registerFunction() method.
+ * @param {String} name The full name of the function including namespacing. This
+ * is the name of the function that is stored in the report.
+ * @return {Void}
+ * @method unregisterFunction
+ * @static
+ */
+ unregisterFunction : function(name /*:String*/, unregisterPrototype /*:Boolean*/) /*:Void*/{
+
+ //see if the method has been registered
+ if (L.isFunction(container[name])){
+
+ //check to see if you should unregister the prototype
+ if (unregisterPrototype){
+ this.unregisterObject(name + ".prototype", container[name].prototype);
+ }
+
+ //get original data
+ var owner /*:Object*/ = container[name].__yuiOwner,
+ funcName /*:String*/ = container[name].__yuiFuncName;
+
+ //delete extra information
+ delete container[name].__yuiOwner;
+ delete container[name].__yuiFuncName;
+
+ //replace instrumented function
+ owner[funcName] = container[name];
+
+ //delete supporting information
+ delete container[name];
+ }
+
+
+ },
+
+ /**
+ * Unregisters an object for profiling. It takes the object and looks for functions.
+ * When a function is found, unregisterMethod() is called on it. If set to recrusive
+ * mode, it will also unregister objects found inside of this object,
+ * using the same methodology.
+ * @param {String} name The name of the object to unregister.
+ * @param {Boolean} recurse (Optional) Determines if subobject methods should also be
+ * unregistered.
+ * @return {Void}
+ * @method unregisterObject
+ * @static
+ */
+ unregisterObject : function (name /*:String*/, recurse /*:Boolean*/) /*:Void*/{
+
+ //get the object
+ if (L.isObject(container[name])){
+ var object = container[name];
+
+ for (var prop in object) {
+ if (typeof object[prop] == "function"){
+ this.unregisterFunction(name + "." + prop);
+ } else if (typeof object[prop] == "object" && recurse){
+ this.unregisterObject(name + "." + prop, recurse);
+ }
+ }
+
+ delete container[name];
+ }
+
+ }
+
+
+ };
+