Javascript Profiling: Difference between revisions

no edit summary
No edit summary
No edit summary
Line 9: Line 9:
There will be a global <tt>Profiler</tt> object available to instantiate to begin profiling other objects. The <tt>Profiler</tt> object has the following methods:
There will be a global <tt>Profiler</tt> object available to instantiate to begin profiling other objects. The <tt>Profiler</tt> object has the following methods:


* <tt>addProfilee : context &rarr; unit</tt> - Adds a new context (is this the right abstraction?) as an object which is being profiled. All further code executions of the script will be candidates for profiling and information can be learned of from the information below. Throws an error if the context is already being profiled by this instance.
* <tt>new Profiler()</tt> - constructor takes no arguments, creates an instance for the invoking context.
* <tt>removeProfilee : context &rarr; bool</tt> - Removes a context from being profiled, returning whether it was actually removed or not (possibly throw an error instead?). Throws an error if the context is currently being profiled.
* <tt>startProfiling : context &rarr; unit</tt> - Starts profiling the specified context. If the context is currently being profiled by another <tt>Profiler</tt> instance (including this one), then an error is thrown.
* <tt>info : context &rarr; stack list</tt> - Fetches information about an object which is being profiled. The list returned is detailed below. Throws an error if the context provided isn't being profiled by this <tt>Profiler</tt> instance.
* <tt>isProfiling : context &rarr; bool</tt> - Returns whether the specified context is being profiled or not by this instance.
* <tt>startProfiling : context &rarr; unit</tt> - Forces the start of profiling on the specified context. Throws an error if the context is already being profiled or if the context hasn't been added yet. This function also clears all existing profiling information.
* <tt>event : object &rarr; unit</tt> - Records a profiling event for the current context. The event is an object which will eventually be returned in a <tt>Profiler.Stack</tt> object queued up in the <tt>events</tt> field. If the current context is not being profiled by this instance, then an error is thrown.
* <tt>stopProfiling : context &rarr; stack list</tt> - Forces stopping profiling on the specified context. Returns all profiling information known about the specified context. Throws an error if the context is not being profiled or if the context hasn't been added yet.
* <tt>info : context &rarr; Profiler.Stack list</tt> - Fetches information about a context which is being profiled. Throws an error if the context provided isn't being profiled by this <tt>Profiler</tt> instance.
* <tt>stopProfiling : context &rarr; Profiler.Stack list</tt> - Ceases profiling the specified context. Returns the same information that <tt>info</tt> returns. Throws an error if the context is not being profiled by this instance.


== The <tt>stack</tt> object ==
Possibly have attributes or methods to enable/disable profiling specific attributes? (custom/memory/time/etc.)


A <tt>stack</tt> object represents an event at a particular stack trace. A stack trace is defined by an ordered list of <tt>&lt;url, line&gt;</tt> pairs where the <tt>url</tt> is the source file of the function and <tt>line</tt> is the line number within the source file. The object would look similarly as follows:
== The <tt>Profiler.Stack</tt> object ==
 
A <tt>Profiler.Stack</tt> object represents an event at a particular stack trace. A stack trace is defined by an ordered list of <tt>&lt;url, line&gt;</tt> pairs where the <tt>url</tt> is the source file of the function and <tt>line</tt> is the line number within the source file. The object would look similarly as follows:


  {                                                       
  {                                                       
Line 37: Line 40:
  }
  }


The <tt>stack</tt> field is the actual stack trace this represents, and the first element is the function which triggered the events, and the subsequent elements are the callers of the previous element. The <tt>events</tt> field is a list of all events related to this stack trace. Events are added internally, but custom events can also be added via <tt>profiler.event</tt>.
The <tt>stack</tt> field is the actual stack trace this represents, and the first element is the function which triggered the events, and the subsequent elements are the callers of the previous element. The <tt>events</tt> field is a list of all events related to this stack trace. Events are added internally, but custom events can also be added via <tt>event</tt>.


Possibly events would also be filtered out? This is more relevant to instrumented C++ functions, I would imagine that all JS events would be public to all <tt>Profiler</tt>s
Possibly events would also be filtered out? This is more relevant to instrumented C++ functions, I would imagine that all JS events would be public to all <tt>Profiler</tt>s
== The Profilee ==
A script being profiled also has control over how it's being profiled. These are the methods by which the script can control profiling:
* <tt>profilee.start() : unit &rarr; unit</tt> - This begins profiling the current page, setting up all necessary internal information. Throws an error if profiling has already been started.
* <tt>profilee.running() : unit &rarr; bool</tt> - Tests whether the profiler is currently running, returning <tt>true</tt> if it is or <tt>false</tt> otherwise.
* <tt>profilee.event(a) : object &rarr; unit</tt> - Fires a custom profiling event from Javascript. The provided object is used to identify the event. Throws an error if profiling is not currently running.
* <tt>profilee.end() : unit &rarr; stack list</tt> - Finishes the profiling process, cleaning up all internal state. The returned array is a list of <tt>stack</tt> objects (described below). Throws an error if profiling is not currently running.


== Use Cases ==
== Use Cases ==


Here's some example use cases for when profiling is wanted and how they would use the API provided above. It's assumed that there's not both a <tt>Profiler</tt> interacting with a page using <tt>profilee</tt> methods because some weird results and possibly errors could be thrown. (Am I correct in assuming that this is a case that shouldn't be worried about in great detail?)
Here's some example use cases for when profiling is wanted and how they would use the API provided above.


=== Test Cases ===
=== Test Cases ===


Each test case desiring profiling would call <tt>profilee.start()</tt>, run for awhile, and then <tt>profilee.end()</tt>. The information would be gathered fromt he call to <tt>end</tt>. No one else is interested in the information, there's no interaction with a <tt>Profiler</tt> object.
The test suite would initially create a <tt>Profiler</tt> object and then start/stop profiling the current page on each call to <tt>startProfiling</tt>/<tt>stopProfiling</tt> and the information returned from <tt>stopProfiling</tt> would be what is displayed.


=== Extension ===
=== Extension ===


Opened on a page and creates its own <tt>Profiler</tt> object. It then attaches itself to the current page via <tt>addProfilee</tt> and then forces the page to start profiling with <tt>startProfiling</tt> (probably a button to be hit). Some time later <tt>stopProfiling</tt> is used to get information about the run of profiling (again probably a button being hit) and then all of the information is sorted through and displayed in some fancy fashion.
Opened on a page and creates its own <tt>Profiler</tt> object. It then profiles the current page via <tt>startProfiling</tt> (probably a button to be hit). Some time later <tt>stopProfiling</tt> is used to get information about the run of profiling (again probably a button being hit) and then all of the information is sorted through and displayed in some fancy fashion.


The page being profiled is unaware that it's being profiled, and there's nothing that it needs to do to help it along. If it so desires, it could conditionally call <tt>profilee.event()</tt> to learn some interesting information.
The page being profiled is unaware that it's being profiled, and there's nothing that it needs to do to help it along. If it so desires, it could conditionally call <tt>profilee.event()</tt> to learn some interesting information.


= Implementation =
= Implementation =
22

edits