NAME
Kernel::Prof – Profiling made easy
SYNOPSIS
A simple example:
use Kernel::Prof;
{
my $Profiler = Kernel::Prof->New->Run();
# SLOW CODE.
}
# $Profiler goes out of scope.
The profiler instance above handles everything!
And once it goes out of scope, it will generate the profiling results in an html format for easy viewing with a browser.
Or as a one-liner:
$ perl -I. -IKernel/cpan-lib -MKernel::Prof -E '
my $p = Kernel::Prof->New->Run();
my $s = 0;
$s+=$_ for 1..100;
say $s;
'
DESCRIPTION
Kernel::Prof (kprof) aims to simplify profiling in Perl by providing a powerful, yet convenient, easy-to-use tool for analyzing code performance.
Whether profiling a quick one-liner or monitoring a more complex system, this tool offers flexibility with unmatched ease of integration.
Profiling Stages
Understanding the different stages of profiling can serve to be useful when using kprof (or at least when updating it).
+-------+-------------------------+
| Stage | Description |
+-------+-------------------------+
| 1 | Environment Setup |
| 2 | Code Initialization |
| 3 | Profiling Start |
| 4 | Profiling Stop |
| 5 | Code Finalization |
| 6 | Environment Restoration |
+-------+-------------------------+
Stage 1: Environment Setup
Special environmental variables must be set prior to running kprof. Failure to do so may result in incomplete data in the profiling results!
export PERL5OPT=-d:NYTProf
export NYTPROF='trace=0:start=no:addpid=1'
PERL5OPT
Described in L<perldoc run>
-d:NYTProf Instructs the perl debugger to use Devel::NYTProf.
NYTPROF
L<https://metacpan.org/pod/Devel::NYTProf#NYTPROF-ENVIRONMENT-VARIABLE>
trace=0 Do not output trace information
to the screen when profiling.
start=no Do not start profiling right away.
addpid=1 Appends the pid to the output file
(critical to have when forking).
These settings are recommended to improve the performance of the profiler:
calls=0 Overview without time usage.
slowops=0 Do not go into core operations (like sleep).
As per the documentation
"Generally speaking, setting calls=0 and slowops=0 will give you a
useful boost with the least loss of detail."
Stage 2: Code Initialization
The program starts to run.
Due to stage 1, the profiler is placed into "standby" mode which has these effects:
Standby mode has source file awareness. (important for a later stage), but without actually recording anything.
Stage 3: Profiling Start
Starting profiling can be compared to pressing a global record button. Once activated, all subsequent activities are saved to a file in a machine-readable format.
Stage 4: Profiling Stop
Stopping profiling is like pressing a global stop button.
It is crucial to stop profiling properly, as incomplete results may render the data useless. As mentioned in Devel::NYTProf:
"NYTProf writes some important data to the data file
when finishing profiling."
At this stage, kprof will attempt to finalize the saved profiling with crucial data which was exclusively stored in-memory.
If possible, kprof will also attempt to run nytprofhtml as well as compressing the results into a tar file when applicable.
Should the profiler fail to generate the html results (this should not happen):
- Try to manually rerun the C<nytprofhtml> command.
- Do not try to copy the raw results (.out) file to another
machine since that may fail. The machine that made *.out*
should run nytprofhtml.
At the end of this stage, the profiler is again placed into standby mode and continues to only observe and wait for an incoming trigger to run again.
Stage 5: Code Finalization
The program continues running as if the profiler was never invoked.
Stage 6: Environment Restoration
Once profiling is complete, it is important to restore the environment to its original condition. Most likely can simply run these commands:
unset PERL5OPT
unset NYTPROF
Modes of Operation
This tool is designed to work in 2 distinct modes which differ in when to start and stop the capturing of data.
Transient Mode
Simple/Scoped/Short-term mode.
This mode is designed for profiling a scope of code.
{
my $Profiler = Kernel::Prof->New->Run();
...
}
Profiling begins once that kprof object is made.
And simply, once the kprof object goes out of scope, the results would be generated.
Pretty straight forward indeed!
Continuous Mode
Long term mode.
This mode is specifically designed to handle many concurrent processes like in a webserver. This interprocess communication is handled using a shared MemoryMap whose presence enables continuous mode.
Also, its important to have some sort of "triggers" to tell the workers/processes when to start profiling and when to end. These are referred here as start and stop flags respectively.
Just as important almost, this mode needs to have a timer after whose expiration, the system should automatically stop profiling. This ensures that profiling is not accidentally forgotten to be disabled and thereby consume all system resources. This timer can be set using StopAfterNMinutes.
Example of using continuous mode:
$ perl -I. -IKernel/cpan-lib -MKernel::Prof -MMojo::MemoryMap -E '
my $Map = Mojo::MemoryMap->new();
my $Profiler = Kernel::Prof->New(
MemoryMap => $Map,
);
while(1){
$Profiler->Run();
say "HERE";
sleep 5;
}
'
The above starts a server of sorts.
Then one can start recording after running:
$ touch nytprof/work/start
Similarly to stop recording:
$ touch nytprof/work/stop
Progressive Stopping
Repeated invocations of touch stop will cause the processes to respond with increasing urgency.
If a process is hanging, try issuing the stop command again to increase the urgency:
$ touch nytprof/work/stop
Stop Urgency Table:
# | Signal | Effect
------------------------------------------------------------
1 | PROF | Graceful stop.
2 | BUS | Aggressive stop while still generating results.
3 | KILL | Immediate stop, but no generated results.
CAVEATS
No Free Lunch
Keep in mind that profiling does incur an administrative cost on the system and one can expect performance to drop during the process.
TODO
KProf
Daemon
Console
WebServer Plugin
Wrapper
Service
Config
Summary
Test
Documentation
QA
Inform
Colors
Colors are extensively used in the output to enhance readability and clarify the profiling flow:
+-----------------+-----------------------------------+
| Color | Usage |
+-----------------+-----------------------------------+
| RED | Error information. |
| YELLOW | Important information. |
| DARK | Info/debug information. |
| GREEN | Control-clickable output. |
| CYAN | Actions like renamed, removed |
| BLUE | Starting/stopping profiling. |
| ON_BLUE | Detected trigger or caught signal |
| ON_RED | Detected an error signal. |
| ON_BRIGHT_BLACK | Running external command. |
+-----------------+-----------------------------------+
METHODS
SetEnvironmentalVariables
Sets these environment variables:
PERL5OPT
NYTPROF
CheckEnvironment
Checks that the environment is setup.
Can/should be called by a wrapper before trying to instantiate a new kprof instance.
GetConfig
Returns the profiler configuration settings.
New
Creates and returns a kprof instance.
my $Profiler = Kernel::Prof->New( %Options );
Returns undef should there be issues.
General Options
These are general options that can be used regardless of the mode.
Name => "my", # Name of the results file/folder.
RootDir => "nytprof", # Root folder for all sub folders of results and triggers.
WorkDir => "$RootDir/work", # Folder to store results.
Log => "$WorkDir/log", # Profiler log.
CompressResults => 0, # Generate a tar ball of the results and remove the data.
UseFlameGraph => 0, # Generate the flame graph (slower).
(Above values are the defaults).
Continuous Mode Options
These options only have an effect during continuous mode.
MemoryMap => undef, # For IPC (multiple processes).
StopAfterNMinutes => 0, # Automatically stop after N minutes.
StartFlag => "$WorkDir/start", # File to tell the profiler to begin recording.
StopFlag => "$WorkDir/stop", # File to tell the profiler to finish recording.
NotifyFlag => "$WorkDir/notify", # Notification if profiling is active.
(Above values are the defaults).
Run
Runs the next tick of the profiler.
Kernel::Prof->Run();
Depends on the mode:
- Transient: will start profiling right away.
- Continuous: handles triggers, start/stop profiling
as needed (according to the trigger).
Name
Specifies a new name to use for the result data.
(Useful for forked processes.)
DESTROY
Probably will not be called directly. Instead, simply undefine the kprof instance to trigger this method:
my $Profiler = Kernel::Prof->New->Run();
...
undef $Profiler;
