22
edits
No edit summary |
No edit summary |
||
| Line 4: | Line 4: | ||
As an idea of what should be possible to build on top of this API, see [http://unity3d.com/support/documentation/Manual/Profiler.html Unity's profiler], | As an idea of what should be possible to build on top of this API, see [http://unity3d.com/support/documentation/Manual/Profiler.html Unity's profiler], | ||
== The Profiler object == | == The Profiler object == | ||
There will be a global <tt>Profiler</tt> object available to instantiate to begin profiling other | There will be a global <tt>Profiler</tt> object available to instantiate to begin profiling other runtimes. For each of the methods below, if an optional 'obj' parameter is taken, that is the specification of what runtime to modify profiling of. If the object is specified, then the object's runtime is used. Otherwise if no object is specified, the current runtime is used. The <tt>Profiler</tt> object has the following methods: | ||
<dl> | <dl> | ||
| Line 15: | Line 13: | ||
<dd>The constructor takes no arguments | <dd>The constructor takes no arguments | ||
<dt> | <dt>start([obj, [sample_rate, [max_samples]]]) | ||
<dd> | <dd>Begins profiling. All arguments are optional. If no object is specified, then the current runtime of execution will be profile. Otherwise the specified object's runtime will be profiled. If the object's runtime (or the current runtime if obj isn't provided) is already being profiled by this Profiler instance, an error is thrown. | ||
The sample rate is the time between samples of the call stack specified in microseconds (defaults to 1000 = 1ms). The sample rate is mostly a guideline as the platform being run might not guarantee the granularity of timing. Samples will not happen more frequently than the specified rate, but may occur more infrequently. | The sample rate is the time between samples of the call stack specified in microseconds (defaults to 1000 = 1ms). The sample rate is mostly a guideline as the platform being run might not guarantee the granularity of timing. Samples will not happen more frequently than the specified rate, but may occur more infrequently. | ||
| Line 23: | Line 21: | ||
If some other Profiler object is profiling the specified runtime, then an error is thrown if the sample rate or maximum sample count is different. Eventually a call to stopProfiling() must be paired with this call to cease data collection. | If some other Profiler object is profiling the specified runtime, then an error is thrown if the sample rate or maximum sample count is different. Eventually a call to stopProfiling() must be paired with this call to cease data collection. | ||
<dt>isProfiling(obj) | <dt>isProfiling([obj]) | ||
<dd>Returns whether profiling is turned on for the specified runtime | <dd>Returns whether profiling is turned on for the specified runtime | ||
<dt>frame() | <dt>frame() | ||
<dd> | <dd>Fetches an object to represent the current stack trace to be later returned via results(). This object can have any properties attached to it and will persist across different invocations of frame() so long as the same backtrace is present each time. All information specified here will later be available via results() with the full backtrace listed. By default this returns an empty object with no properties. If the current runtime is not being profiled, then an error is thrown. | ||
<dt> | <dt>results([obj]) | ||
<dd>Returns all profile information for the specified object's runtime. The data returned is all that is collected between the last invocation of | <dd>Returns all profile information for the specified object's runtime. The data returned is all that is collected between the last invocation of reset() and all the profile data. | ||
<dt> | <dt>reset([obj]) | ||
<dd> | <dd>Resets all information known about the specified runtime. This includes samples and also frame() information. Throws an error if the runtime in question isn't being profiled. | ||
<dt> | <dt>stop([obj]) | ||
<dd>Ceases profiling on the specified runtime. | <dd>Ceases profiling on the specified runtime. If the runtime in question isn't being profiled, an error is thrown. | ||
</dl> | </dl> | ||
=== The return of <tt>. | === The return of <tt>.results()</tt> === | ||
The return value is an object which is a hash containing all the information. The hash can loosely be viewed as a trie. Here's some example code: | The return value is an object which is a hash containing all the information. The hash can loosely be viewed as a trie. Here's some example code: | ||
| Line 61: | Line 59: | ||
} | } | ||
p. | p.start(); | ||
foo(4000000); | foo(4000000); | ||
bar(200); | bar(200); | ||
p. | p.stop(); | ||
print(JSON.stringify(p. | print(JSON.stringify(p.results())) | ||
And the following hash would be printed: | And the following hash would be printed: | ||
{ | { | ||
samples: 624, | |||
children: [ | children: [ | ||
{ | { | ||
function: { file: 'input.js', line: 1 }, | function: { file: 'input.js', line: 1, name: '<top level>' }, | ||
site: { file: 'input.js', line: 25 }, | site: { file: 'input.js', line: 25 }, | ||
samples: 624, | |||
children: [ | children: [ | ||
{ | { | ||
function: { file: 'input.js', line: 1, name: 'foo' }, | function: { file: 'input.js', line: 1, name: 'foo' }, | ||
site: { file: 'input.js', line: 7 }, | site: { file: 'input.js', line: 7 }, | ||
samples: 195, | |||
selfCount: 195 | |||
}, { | }, { | ||
function: { file: 'input.js', line: 1, name: 'foo' }, | function: { file: 'input.js', line: 1, name: 'foo' }, | ||
site: { file: 'input.js', line: 11 }, | site: { file: 'input.js', line: 11 }, | ||
samples: 429, | |||
selfCount: 429 | |||
} | } | ||
] | ] | ||
}, { | }, { | ||
function: { file: 'input.js', line: 1}, | function: { file: 'input.js', line: 1 }, | ||
site: { file: 'input.js', line: 26}, | site: { file: 'input.js', line: 26 }, | ||
children: [ | children: [ | ||
{ | { | ||
| Line 115: | Line 113: | ||
<dl> | <dl> | ||
<dt> | <dt>samples | ||
<dd>This is an integer value of the number of ticks while this function's frame was on the stack. This is useful when counting total time spent in a function. It should be true that: <tt> | <dd>This is an integer value of the number of ticks while this function's frame was on the stack. This is useful when counting total time spent in a function. It should be true that: <tt>samples = selfCount + children.sum('samples')</tt> | ||
<dt> | <dt>selfCount | ||
<dd>This is an integer value like " | <dd>This is an integer value like "samples," but instead only counts the time spent in the function itself. When a sample is taken and a function is currently running (it's the top of the stack), it's selfCount is increased. | ||
</dl> | </dl> | ||
== Use Cases == | == Use Cases == | ||
| Line 133: | Line 125: | ||
=== Test Cases === | === Test Cases === | ||
The test suite would initially create a <tt>Profiler</tt> object and then start/stop profiling the current page on each call to <tt> | The test suite would initially create a <tt>Profiler</tt> object and then start/stop profiling the current page on each call to <tt>start</tt>/<tt>stop</tt> and the information returned from <tt>results</tt> would be what is displayed. Between each test, the <tt>reset</tt> method would be used to prevent pollution between runs. | ||
=== Extension === | === Extension === | ||
Opened on a page and creates its own <tt>Profiler</tt> object. It then profiles the current page via <tt> | Opened on a page and creates its own <tt>Profiler</tt> object. It then profiles the current page via <tt>start</tt> (probably a button to be hit). Some time later <tt>results</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. | The page being profiled is unaware that it's being profiled, and there's nothing that it needs to do to help it along. | ||
edits