Profiling UI Responsiveness
Author: Tomas Pavek
$Revision: 1.8 $
$Date: 2002/10/18 13:18:03 $
Document history: available in
CVS
Goal
We want to be able to profile user actions using OptimizeIt Profiler tool. More
specifically, we want to profile performance of any user action between invocation of the action and finishing the action in the
IDE. Technically, we just extend the Measuring UI Responsiveness
technique by adding profiling capability. Please read the document first, as I often refer to it in this
text.
Technique
Invoking profiler from a program can be done via special OptimizeIt API
calls. Following methods from intuitive.audit.Audit class
can be used:
public static void enableCPUProfiler(ThreadGroup aGroup)
public static void disableCPUProfiler(ThreadGroup aGroup)
These methods require specifying a ThreadGroup -- a group of
threads that should be
monitored. It is possible to profile just the current thread using the same methods without
parameters, but it
is better to monitor all threads, at least when profiling NetBeans.
We may also generate a snapshot, storing the profiling data in a file that
can be opened in OptimizeIt tool later:
public static void generateSnapshot(int optionMask)
Following the general measuring technique, we may continue hacking java.awt.EventQueue.
Hacking JDK directly brings problem with calling the Audit class methods -- they cannot be
called directly, but just via reflection. The reason is that Audit
class is not (and cannot) be on boot classpath when the program is running. If
you add the API calls on exact places in the program's code, no reflection is
needed, direct
calls work normally.
To make the profiling invocation work, it's necessary to start the program in
special audit mode, add some OptimizeIt libraries to classpath, and set some
parameters. An example of starting NetBeans on Windows is shown below. Once the
program is started, run OptimizeIt Profiler, attach it to the program, and you may
start with profiling.
When to start and stop profiling?
Let's follow the general responsiveness measuring approach. We want to start profiling when an user action occurs, and stop it when the
action is complete (a
paint occurs). The start and stop conditions should be specified better
than just in simple time measuring, as it is not desirable to profile every
user action, but only certain actions we are interested in. This can be done by watching only
certain input events, so e.g. start profiling only when Enter is
pressed. And when to stop profiling? As more paints can happen before an
action completes, we cannot just stop with the first paint, but need a
configurable paint count to be watched. To find out what number of paints is
done for an action, we need to turn the profiling off temporarily to test the action.
In case the number of paints cannot be reasonably defined, profiling could be
stopped by pressing the starting key again. So
we see that some further profiling configuration is needed to be done during
runtime (more information below).
I will not describe how this all can be exactly implemented, you may look at the
hacked code directly if
interested:
Usage
Here are the steps to make it all work. The examples apply on Windows.
Get the diffs (for JDK 1.4.0
or for JDK 1.4.1), apply the changes to JDK
sources.
Compile the changed sources.
Pack produced class files into a zip file, keeping the right package structure.
Modify 'ide.policy' file (in 'bin' directory of NetBeans) to grant security permissions to
OptimizeIt libraries running together with NetBeans; e.g. add a section like:
grant codeBase "file:///C:/OptimizeitSuite/OptimizeitSuite42/-" {
permission java.security.AllPermission;
};
Start the IDE from the 'bin' directory using a special command with all
parameters and switches as needed. In that command you must:
-
enable the audit system by -Xrunpri:dmp=1 switch,
-
add oibcp.jar file from OptimizeIt to boot classpath
using -Xbootclasspath/a: switch,
-
add optit.jar file from OptimizeIt to classpath using -cp:a switch,
-
add the zip file with hacked JDK classes to boot classpath using -Xbootclasspath/p:
switch,
-
add -dmp -enableAPI switches for audit system.
The command then could look like:
runide.exe -J-Xrunpri:dmp=1 -J-Xbootclasspath/p:D:\hacked_jdk\hack_jdk140_profiling.zip
-J-Xbootclasspath/a:C:\OptimizeitSuite\OptimizeitSuite42\lib\oibcp.jar
-cp:a C:\OptimizeitSuite\OptimizeitSuite42\lib\optit.jar
-mainclass intuitive.audit.Audit -dmp -enableAPI org.netbeans.Main
Run OptimizeIt Profiler and attach it to the running IDE (using Ctrl+A).
After the IDE comes up, bring it to the situation when you can start
the action to be profiled. Don't use Enter key as it starts the
profiling by default.
Press ` key (the key below Esc key) to bring up a
configuration dialog where you can set parameters like:
-
what key starts/stops profiling (Enter by default; other keys may be
used too, e.g. right arrow for profiling tree node
expansion, down arrow for combobox selection, Shift+F10 for popup menu
invocation, etc),
-
for how many paints profiling runs,
-
what threads should be monitored,
-
whether to generate a snapshot in the end.
Note you may also disable the profiling here (then only events and
measured time are printed to console) and enable it later.

When ready to start the action to be profiled, switch to OptimizeIt and press the
"Start CPU profiler" button. This does not start profiling, but
makes the OptimizeIt "listen" to the calls from the application.
Switch back to NetBeans and invoke the action using the starting key.
Profiler is started, monitoring the application until specified number of paints
occurs, in which moment profiling is stopped (generating snapshot if set to do so).
Switch back to OptimizeIt and press "Stop CPU profiler"
button -- and OptimizeIt will show the results.
That's all. You may repeat the profiling for various user actions just within
one run of the IDE. The Profiling Configuration dialog should help.
Note: There is a problem with OptimizeIt 4.2 not stopping on API call
when Instrumentation profiling is used. (It works without problems for Sampler
profiling method.) The stop call is performed but profiling simply
continues until Stop button is pressed in the OptimizeIt Profiler tool. This may
distort the results. If facing this problem, set a snapshot to be generated. The
snapshot is taken at the right moment, though profiling may continue. You can open the
snapshot later in the OptimizeIt Profiler tool.
 
Please send comments to nbdev.